Example #1
0
 double DgsReduction::getParameter(std::string algParam,
     MatrixWorkspace_sptr ws, std::string altParam)
 {
   double param = this->getProperty(algParam);
   if (EMPTY_DBL() == param)
   {
     param = ws->getInstrument()->getNumberParameter(altParam)[0];
   }
   return param;
 }
Example #2
0
/** Get a pointer to an instrument in one of 3 ways: InputWorkspace,
 * InstrumentName, InstrumentFilename
 * @param alg :: algorithm from which to get the property values.
 * */
Geometry::Instrument_const_sptr
LoadCalFile::getInstrument3Ways(Algorithm *alg) {
  MatrixWorkspace_sptr inWS = alg->getProperty("InputWorkspace");
  std::string InstrumentName = alg->getPropertyValue("InstrumentName");
  std::string InstrumentFilename = alg->getPropertyValue("InstrumentFilename");

  // Some validation
  int numParams = 0;
  if (inWS)
    numParams++;
  if (!InstrumentName.empty())
    numParams++;
  if (!InstrumentFilename.empty())
    numParams++;

  if (numParams > 1)
    throw std::invalid_argument("You must specify exactly ONE way to get an "
                                "instrument (workspace, instrument name, or "
                                "IDF file). You specified more than one.");
  if (numParams == 0)
    throw std::invalid_argument("You must specify exactly ONE way to get an "
                                "instrument (workspace, instrument name, or "
                                "IDF file). You specified none.");

  // ---------- Get the instrument one of 3 ways ---------------------------
  Instrument_const_sptr inst;
  if (inWS) {
    inst = inWS->getInstrument();
  } else {
    Algorithm_sptr childAlg =
        alg->createChildAlgorithm("LoadInstrument", 0.0, 0.2);
    MatrixWorkspace_sptr tempWS = boost::make_shared<Workspace2D>();
    childAlg->setProperty<MatrixWorkspace_sptr>("Workspace", tempWS);
    childAlg->setPropertyValue("Filename", InstrumentFilename);
    childAlg->setPropertyValue("InstrumentName", InstrumentName);
    childAlg->setProperty("RewriteSpectraMap",
                          Mantid::Kernel::OptionalBool(false));
    childAlg->executeAsChildAlg();
    inst = tempWS->getInstrument();
  }

  return inst;
}
Example #3
0
/** Checks that the input workspace all exist, that they are the same size, have
 * the same units
 *  and the same instrument name. Will throw if they don't.
 *  @param  inputWorkspaces The names of the input workspaces
 *  @return A list of pointers to the input workspace, ordered by increasing
 * frame starting point
 *  @throw  Exception::NotFoundError If an input workspace doesn't exist
 *  @throw  std::invalid_argument    If the input workspaces are not compatible
 */
std::list<API::MatrixWorkspace_sptr>
MergeRuns::validateInputs(const std::vector<std::string> &inputWorkspaces) {
    std::list<MatrixWorkspace_sptr> inWS;

    std::string xUnitID;
    std::string YUnit;
    bool dist(false);
    // Going to check that name of instrument matches - think that's the best
    // possible at the moment
    //   because if instrument is created from raw file it'll be a different
    //   object
    std::string instrument;

    for (size_t i = 0; i < inputWorkspaces.size(); ++i) {
        MatrixWorkspace_sptr ws;
        // Fetch the next input workspace - throw an error if it's not there
        try {
            ws = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
                     inputWorkspaces[i]);
            if (!ws) {
                g_log.error() << "Input workspace " << inputWorkspaces[i]
                              << " not found.\n";
                throw Kernel::Exception::NotFoundError("Data Object",
                                                       inputWorkspaces[i]);
            }
            inWS.push_back(ws);
        } catch (Exception::NotFoundError &) {
            g_log.error() << "Input workspace " << inputWorkspaces[i]
                          << " not found.\n";
            throw;
        }
        // Check that it has common binning
        if (!WorkspaceHelpers::commonBoundaries(inWS.back())) {
            g_log.error("Input workspaces must have common binning for all spectra");
            throw std::invalid_argument(
                "Input workspaces must have common binning for all spectra");
        }
        // Check a few things are the same for all input workspaces
        if (i == 0) {
            xUnitID = ws->getAxis(0)->unit()->unitID();
            YUnit = ws->YUnit();
            dist = ws->isDistribution();
            instrument = ws->getInstrument()->getName();
        } else {
            testCompatibility(ws, xUnitID, YUnit, dist, instrument);
        }
    }

    // Order the workspaces by ascending frame (X) starting point
    inWS.sort(compare);

    return inWS;
}
/** Sets the properties of the reference (usually first) workspace,
 * to later check the compatibility of the others with the reference
 * @param ref : the reference workspace
 */
void RunCombinationHelper::setReferenceProperties(MatrixWorkspace_sptr ref) {
  m_numberSpectra = ref->getNumberHistograms();
  m_numberDetectors = ref->detectorInfo().size();
  m_xUnit = ref->getAxis(0)->unit()->unitID();
  m_spectrumAxisUnit = ref->getAxis(1)->unit()->unitID();
  m_yUnit = ref->YUnit();
  m_isHistogramData = ref->isHistogramData();
  m_isScanning = ref->detectorInfo().isScanning();
  m_instrumentName = ref->getInstrument()->getName();
  if (m_numberSpectra) {
    m_hasDx.reserve(m_numberSpectra);
    for (unsigned int i = 0; i < m_numberSpectra; ++i)
      m_hasDx.push_back(ref->hasDx(i));
  }
}
/**
 * Get the detector component. Use the name provided as a property as the basis
 *for the lookup as a priority.
 *
 * Throws if the name is invalid.
 * @param workspace : Workspace from instrument with detectors
 * @param isPointDetector : True if this is a point detector. Used to guess a
 *name.
 * @return The component : The component object found.
 */
boost::shared_ptr<const Mantid::Geometry::IComponent>
SpecularReflectionAlgorithm::getDetectorComponent(
    MatrixWorkspace_sptr workspace, const bool isPointDetector) const {
  boost::shared_ptr<const IComponent> searchResult;
  if (!isPropertyDefault("SpectrumNumbersOfDetectors")) {
    const std::vector<int> spectrumNumbers =
        this->getProperty("SpectrumNumbersOfDetectors");
    const bool strictSpectrumChecking =
        this->getProperty("StrictSpectrumChecking");
    checkSpectrumNumbers(spectrumNumbers, strictSpectrumChecking, g_log);
    auto specToWorkspaceIndex = workspace->getSpectrumToWorkspaceIndexMap();
    DetectorGroup_sptr allDetectors = boost::make_shared<DetectorGroup>();
    const auto &spectrumInfo = workspace->spectrumInfo();
    for (auto index : spectrumNumbers) {
      const size_t spectrumNumber{static_cast<size_t>(index)};
      auto it = specToWorkspaceIndex.find(index);
      if (it == specToWorkspaceIndex.end()) {
        std::stringstream message;
        message << "Spectrum number " << spectrumNumber
                << " does not exist in the InputWorkspace";
        throw std::invalid_argument(message.str());
      }
      const size_t workspaceIndex = it->second;
      auto detector = workspace->getDetector(workspaceIndex);
      if (spectrumInfo.isMasked(workspaceIndex))
        g_log.warning() << "Adding a detector (ID:" << detector->getID()
                        << ") that is flagged as masked.\n";
      allDetectors->addDetector(detector);
    }
    searchResult = allDetectors;
  } else {
    Mantid::Geometry::Instrument_const_sptr inst = workspace->getInstrument();
    std::string componentToCorrect =
        isPointDetector ? "point-detector" : "linedetector";

    if (!isPropertyDefault("DetectorComponentName")) {
      componentToCorrect = this->getPropertyValue("DetectorComponentName");
    }
    searchResult = inst->getComponentByName(componentToCorrect);
    if (searchResult == nullptr) {
      throw std::invalid_argument(componentToCorrect +
                                  " does not exist. Check input properties.");
    }
  }

  return searchResult;
}
  /** Execute the algorithm.
   */
  void CreatePeaksWorkspace::exec()
  {
    MatrixWorkspace_sptr instWS = getProperty("InstrumentWorkspace");

    PeaksWorkspace_sptr out(new PeaksWorkspace());
    setProperty("OutputWorkspace", out);
    int NumberOfPeaks = getProperty("NumberOfPeaks");

    if (instWS)
    {
      out->setInstrument(instWS->getInstrument());
      // Create some default peaks
      for (int i=0; i < NumberOfPeaks; i++)
      {
        out->addPeak( Peak(out->getInstrument(), out->getInstrument()->getDetectorIDs(true)[0], 1.0) );
      }
    }
  }
    /**
     * Update the list of analysers based on an instrument workspace.
     *
     * @param ws Instrument workspace
     * @return If the workspace contained valid analysers
     */
    bool IndirectInstrumentConfig::updateAnalysersList(MatrixWorkspace_sptr ws)
    {
      if(!ws)
        return false;

      QList<QPair<QString, QString>> instrumentModes;
      Instrument_const_sptr instrument = ws->getInstrument();

      std::vector<std::string> ipfAnalysers = instrument->getStringParameter("analysers");
      QStringList analysers;
      if(ipfAnalysers.size() > 0)
        analysers = QString::fromStdString(ipfAnalysers[0]).split(",");

      // Do not try to display analysers if there are none
      if(analysers.size() == 0)
        return false;

      for(auto it = analysers.begin(); it != analysers.end(); ++it)
      {
        QString analyser = *it;
        std::string ipfReflections = instrument->getStringParameter("refl-" + analyser.toStdString())[0];
        QStringList reflections = QString::fromStdString(ipfReflections).split(",");

        if(m_removeDiffraction && analyser == "diffraction")
          continue;

        if(m_forceDiffraction && analyser != "diffraction")
          continue;

        if(reflections.size() > 0)
        {
          QVariant data = QVariant(reflections);
          m_uiForm.cbAnalyser->addItem(analyser, data);
        }
        else
        {
          m_uiForm.cbAnalyser->addItem(analyser);
        }
      }

      return true;
    }
/** Loads the parameters from the Nexus file if possible, else from a parameter
 *file
 *  into the specified workspace
 * @param nxfile :: open NeXus file
 * @param localWorkspace :: workspace into which loading occurs
 *
 *  @throw FileError Thrown if unable to parse XML file
 */
void LoadIDFFromNexus::LoadParameters(
    ::NeXus::File *nxfile, const MatrixWorkspace_sptr localWorkspace) {

  std::string parameterString;

  // First attempt to load parameters from nexus file.
  nxfile->openGroup("instrument", "NXinstrument");
  localWorkspace->loadInstrumentParametersNexus(nxfile, parameterString);
  nxfile->closeGroup();

  // loadInstrumentParametersNexus does not populate any instrument params
  // so we do it here.
  localWorkspace->populateInstrumentParameters();

  if (parameterString.empty()) {
    // No parameters have been found in Nexus file, so we look for them in a
    // parameter file.
    std::vector<std::string> directoryNames =
        ConfigService::Instance().getInstrumentDirectories();
    const std::string instrumentName =
        localWorkspace->getInstrument()->getName();
    for (const auto &directoryName : directoryNames) {
      // This will iterate around the directories from user ->etc ->install, and
      // find the first appropriate file
      const std::string paramFile =
          directoryName + instrumentName + "_Parameters.xml";

      // Attempt to load specified file, if successful, use file and stop
      // search.
      if (loadParameterFile(paramFile, localWorkspace))
        break;
    }
  } else { // We do have parameters from the Nexus file
    g_log.notice() << "Found Instrument parameter map entry in Nexus file, "
                      "which is loaded.\n\n";
    // process parameterString into parameters in workspace
    localWorkspace->readParameterMap(parameterString);
  }
}
void SmoothNeighboursDialog::inputWorkspaceChanged(const QString& pName)
{
  UNUSED_ARG(pName);

  m_propertiesWidget->m_groupWidgets[RECTANGULAR_GROUP]->setVisible(false);
  m_propertiesWidget->m_groupWidgets[NON_UNIFORM_GROUP]->setVisible(false);

  std::string inWsName = INPUT_WORKSPACE.toStdString();

  // Workspace should have been set by PropertyWidget before emitting valueChanged
  MatrixWorkspace_sptr inWs = this->getAlgorithm()->getProperty(inWsName);

  if(!inWs)
  {
    // Workspace groups are NOT returned by IWP->getWorkspace(), as they are not MatrixWorkspace,
    // so check the ADS for the GroupWorkspace with the same name
    std::string inWsValue = this->getAlgorithm()->getPointerToProperty(inWsName)->value();

    // If it really doesn't exist, don't do anything
    if(!AnalysisDataService::Instance().doesExist(inWsValue))
      return;

    WorkspaceGroup_sptr inGroupWs = AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>(inWsValue);

    if(inGroupWs)
      // If is a group workspace, use the first workspace to determine the instrument type,
      // as most of the times it will be the same for all the workspaces
      inWs = boost::dynamic_pointer_cast<MatrixWorkspace>(inGroupWs->getItem(0));
    else
      // If is not a GroupWorkspace as well, do nothing
      return;
  }
  Instrument::ContainsState containsRectDetectors = inWs->getInstrument()->containsRectDetectors();

  if(containsRectDetectors == Instrument::ContainsState::Full)
    m_propertiesWidget->m_groupWidgets[RECTANGULAR_GROUP]->setVisible(true);
  else
    m_propertiesWidget->m_groupWidgets[NON_UNIFORM_GROUP]->setVisible(true);
}
/** Execute the algorithm.
 */
void SpecularReflectionPositionCorrect::exec() {

  MatrixWorkspace_sptr inWS = this->getProperty("InputWorkspace");
  const std::string analysisMode = this->getProperty("AnalysisMode");
  auto cloneWS = this->createChildAlgorithm("CloneWorkspace");
  cloneWS->initialize();
  cloneWS->setProperty("InputWorkspace", inWS);
  cloneWS->execute();
  Workspace_sptr tmp = cloneWS->getProperty("OutputWorkspace");
  MatrixWorkspace_sptr outWS =
      boost::dynamic_pointer_cast<MatrixWorkspace>(tmp);

  const double twoThetaIn = this->getProperty("TwoThetaIn");

  auto instrument = outWS->getInstrument();
  IComponent_const_sptr detector =
      this->getDetectorComponent(outWS, analysisMode == pointDetectorAnalysis);
  IComponent_const_sptr sample = this->getSurfaceSampleComponent(instrument);

  correctPosition(outWS, twoThetaIn, sample, detector);

  setProperty("OutputWorkspace", outWS);
}
/**
 * Determine the instrument from the various input parameters.
 *
 * @return The correct instrument.
 */
Instrument_const_sptr CreateChunkingFromInstrument::getInstrument() {
  // try the input workspace
  MatrixWorkspace_sptr inWS = getProperty(PARAM_IN_WKSP);
  if (inWS) {
    return inWS->getInstrument();
  }

  // temporary workspace to hang everything else off of
  MatrixWorkspace_sptr tempWS(new Workspace2D());
  // name of the instrument
  string instName = getPropertyValue(PARAM_INST_NAME);

  // see if there is an input file
  string filename = getPropertyValue(PARAM_IN_FILE);
  if (!filename.empty()) {
    string top_entry_name("entry"); // TODO make more flexible

    // get the instrument name from the filename
    size_t n = filename.rfind('/');
    if (n != std::string::npos) {
      std::string temp = filename.substr(n + 1, filename.size() - n - 1);
      n = temp.find('_');
      if (n != std::string::npos && n > 0) {
        instName = temp.substr(0, n);
      }
    }

    // read information from the nexus file itself
    try {
      NeXus::File nxsfile(filename);

      // get the run start time
      string start_time;
      nxsfile.openGroup(top_entry_name, "NXentry");
      nxsfile.readData("start_time", start_time);
      tempWS->mutableRun().addProperty(
          "run_start", DateAndTime(start_time).toISO8601String(), true);

      // get the instrument name
      nxsfile.openGroup("instrument", "NXinstrument");
      nxsfile.readData("name", instName);
      nxsfile.closeGroup();

      // Test if IDF exists in file, move on quickly if not
      nxsfile.openPath("instrument/instrument_xml");
      nxsfile.close();
      IAlgorithm_sptr loadInst =
          createChildAlgorithm("LoadIDFFromNexus", 0.0, 0.2);
      // Now execute the Child Algorithm. Catch and log any error, but don't
      // stop.
      try {
        loadInst->setPropertyValue("Filename", filename);
        loadInst->setProperty<MatrixWorkspace_sptr>("Workspace", tempWS);
        loadInst->setPropertyValue("InstrumentParentPath", top_entry_name);
        loadInst->execute();
      } catch (std::invalid_argument &) {
        g_log.error("Invalid argument to LoadIDFFromNexus Child Algorithm ");
      } catch (std::runtime_error &) {
        g_log.debug("No instrument definition found in " + filename + " at " +
                    top_entry_name + "/instrument");
      }

      if (loadInst->isExecuted())
        return tempWS->getInstrument();
      else
        g_log.information("No IDF loaded from Nexus file.");

    } catch (::NeXus::Exception &) {
      g_log.information("No instrument definition found in " + filename +
                        " at " + top_entry_name + "/instrument");
    }
  }

  // run LoadInstrument if other methods have not run
  string instFilename = getPropertyValue(PARAM_INST_FILE);

  Algorithm_sptr childAlg = createChildAlgorithm("LoadInstrument", 0.0, 0.2);
  childAlg->setProperty<MatrixWorkspace_sptr>("Workspace", tempWS);
  childAlg->setPropertyValue("Filename", instFilename);
  childAlg->setPropertyValue("InstrumentName", instName);
  childAlg->executeAsChildAlg();
  return tempWS->getInstrument();
}
/**
 * Handles setting default spectra range when an instrument configuration is
 *selected.
 *
 * @param instrumentName Name of selected instrument
 * @param analyserName Name of selected analyser (should always be
 *"diffraction")
 * @param reflectionName Name of diffraction mode selected
 */
void IndirectDiffractionReduction::instrumentSelected(
    const QString &instrumentName, const QString &analyserName,
    const QString &reflectionName) {
  UNUSED_ARG(analyserName);

  // Set the search instrument for runs
  m_uiForm.rfSampleFiles->setInstrumentOverride(instrumentName);
  m_uiForm.rfCanFiles->setInstrumentOverride(instrumentName);

  MatrixWorkspace_sptr instWorkspace = loadInstrument(
      instrumentName.toStdString(), reflectionName.toStdString());
  Instrument_const_sptr instrument = instWorkspace->getInstrument();

  // Get default spectra range
  double specMin = instrument->getNumberParameter("spectra-min")[0];
  double specMax = instrument->getNumberParameter("spectra-max")[0];

  m_uiForm.spSpecMin->setValue(static_cast<int>(specMin));
  m_uiForm.spSpecMax->setValue(static_cast<int>(specMax));

  // Determine whether we need vanadium input
  std::vector<std::string> correctionVector =
      instrument->getStringParameter("Workflow.Diffraction.Correction");
  bool vanadiumNeeded = false;
  bool calibNeeded = false;
  if (correctionVector.size() > 0) {
    vanadiumNeeded = (correctionVector[0] == "Vanadium");
    calibNeeded = (correctionVector[0] == "Calibration");
  }

  if (vanadiumNeeded)
    m_uiForm.swVanadium->setCurrentIndex(0);
  else if (calibNeeded)
    m_uiForm.swVanadium->setCurrentIndex(1);
  else
    m_uiForm.swVanadium->setCurrentIndex(2);

  // Hide options that the current instrument config cannot process
  if (instrumentName == "OSIRIS" && reflectionName == "diffonly") {
    // Disable individual grouping
    m_uiForm.ckIndividualGrouping->setToolTip(
        "OSIRIS cannot group detectors individually in diffonly mode");
    m_uiForm.ckIndividualGrouping->setEnabled(false);
    m_uiForm.ckIndividualGrouping->setChecked(false);

    // Disable sum files
    m_uiForm.ckSumFiles->setToolTip("OSIRIS cannot sum files in diffonly mode");
    m_uiForm.ckSumFiles->setEnabled(false);
    m_uiForm.ckSumFiles->setChecked(false);

  } else {
    // Re-enable sum files
    m_uiForm.ckSumFiles->setToolTip("");
    m_uiForm.ckSumFiles->setEnabled(true);
    m_uiForm.ckSumFiles->setChecked(true);

    // Re-enable individual grouping
    m_uiForm.ckIndividualGrouping->setToolTip("");
    m_uiForm.ckIndividualGrouping->setEnabled(true);

    // Re-enable spectra range
    m_uiForm.spSpecMin->setEnabled(true);
    m_uiForm.spSpecMax->setEnabled(true);
  }
}
Example #13
0
    /** Execute the algorithm.
     */
    void DgsReduction::exec()
    {
      // Reduction property manager
      const std::string reductionManagerName = this->getProperty("ReductionProperties");
      if (reductionManagerName.empty())
      {
        g_log.error() << "ERROR: Reduction Property Manager name is empty" << std::endl;
        return;
      }
      this->reductionManager = boost::make_shared<PropertyManager>();
      PropertyManagerDataService::Instance().addOrReplace(reductionManagerName,
          this->reductionManager);

      // Put all properties except input files/workspaces into property manager.
      const std::vector<Property *> props = this->getProperties();
      std::vector<Property *>::const_iterator iter = props.begin();
      for (; iter != props.end(); ++iter)
      {
        if (!boost::contains((*iter)->name(), "Input"))
        {
          this->reductionManager->declareProperty((*iter)->clone());
        }
      }
      // Determine the default facility
      const FacilityInfo defaultFacility = ConfigService::Instance().getFacility();

      // Need to load data to get certain bits of information.
      Workspace_sptr sampleWS = this->loadInputData("Sample");
      MatrixWorkspace_sptr WS = boost::dynamic_pointer_cast<MatrixWorkspace>(sampleWS);
      this->reductionManager->declareProperty(new PropertyWithValue<std::string>(
          "InstrumentName", WS->getInstrument()->getName()));

      // Check the facility for the loaded file and make sure it's the
      // same as the default.
      const InstrumentInfo info = ConfigService::Instance().getInstrument(WS->getInstrument()->getName());
      if (defaultFacility.name() != info.facility().name())
      {
        std::ostringstream mess;
        mess << "Default facility must be set to " << info.facility().name();
        mess << " in order for reduction to work!";
        throw std::runtime_error(mess.str());
      }

      MatrixWorkspace_sptr sampleMonWS = this->getProperty("SampleInputMonitorWorkspace");

      const bool showIntermedWS = this->getProperty("ShowIntermediateWorkspaces");

      // Get output workspace pointer and name
      MatrixWorkspace_sptr outputWS = this->getProperty("OutputWorkspace");
      std::string outputWsName = this->getPropertyValue("OutputWorkspace");
      if (boost::ends_with(outputWsName, "_spe"))
      {
        boost::erase_all(outputWsName, "_spe");
      }

      // Load the hard mask if available
      MatrixWorkspace_sptr hardMaskWS = this->loadHardMask();
      if (hardMaskWS && showIntermedWS)
      {
        std::string hardMaskName = outputWsName + "_hardmask";
        this->declareProperty(new WorkspaceProperty<>("ReductionHardMask",
            hardMaskName, Direction::Output));
        this->setProperty("ReductionHardMask", hardMaskWS);
      }
      // Load the grouping file if available
      MatrixWorkspace_sptr groupingWS = this->loadGroupingFile("");
      if (groupingWS && showIntermedWS)
      {
        std::string groupName = outputWsName + "_grouping";
        this->declareProperty(new WorkspaceProperty<>("ReductionGrouping",
            groupName, Direction::Output));
        this->setProperty("ReductionGrouping", groupingWS);
      }

      // This will be diagnostic mask if DgsDiagnose is run and hard mask if not.
      MatrixWorkspace_sptr maskWS;

      // Process the sample detector vanadium if present
      Workspace_sptr detVanWS = this->loadInputData("DetectorVanadium", false);
      MatrixWorkspace_sptr detVanMonWS = this->getProperty("DetectorVanadiumInputMonitorWorkspace");
      bool isProcessedDetVan = this->getProperty("UseProcessedDetVan");
      // Process a comparison detector vanadium if present
      Workspace_sptr detVan2WS = this->loadInputData("DetectorVanadium2", false);
      MatrixWorkspace_sptr detVan2MonWS = this->getProperty("DetectorVanadium2InputMonitorWorkspace");
      IAlgorithm_sptr detVan;
      Workspace_sptr idetVanWS;
      if (detVanWS && !isProcessedDetVan)
      {
        std::string detVanMaskName = outputWsName + "_diagmask";

        IAlgorithm_sptr diag = this->createChildAlgorithm("DgsDiagnose");
        diag->setProperty("DetVanWorkspace", detVanWS);
        diag->setProperty("DetVanMonitorWorkspace", detVanMonWS);
        diag->setProperty("DetVanCompWorkspace", detVan2WS);
        diag->setProperty("DetVanCompMonitorWorkspace", detVan2MonWS);
        diag->setProperty("SampleWorkspace", sampleWS);
        diag->setProperty("SampleMonitorWorkspace", sampleMonWS);
        diag->setProperty("HardMaskWorkspace", hardMaskWS);
        diag->setProperty("ReductionProperties", reductionManagerName);
        diag->executeAsChildAlg();
        maskWS = diag->getProperty("OutputWorkspace");

        if (showIntermedWS)
        {
          this->declareProperty(new WorkspaceProperty<>("SampleDetVanDiagMask",
              detVanMaskName, Direction::Output));
          this->setProperty("SampleDetVanDiagMask", maskWS);
        }

        detVan = this->createChildAlgorithm("DgsProcessDetectorVanadium");
        detVan->setProperty("InputWorkspace", detVanWS);
        detVan->setProperty("InputMonitorWorkspace", detVanMonWS);
        detVan->setProperty("MaskWorkspace", maskWS);
        std::string idetVanName = outputWsName + "_idetvan";
        detVan->setProperty("ReductionProperties", reductionManagerName);
        detVan->executeAsChildAlg();
        MatrixWorkspace_sptr oWS = detVan->getProperty("OutputWorkspace");
        idetVanWS = boost::dynamic_pointer_cast<Workspace>(oWS);

        if (showIntermedWS)
        {
          this->declareProperty(new WorkspaceProperty<>("IntegratedNormWorkspace",
              idetVanName, Direction::Output));
          this->setProperty("IntegratedNormWorkspace", idetVanWS);
        }
      }
      else
      {
        idetVanWS = detVanWS;
        maskWS = boost::dynamic_pointer_cast<MatrixWorkspace>(idetVanWS);
        detVanWS.reset();
      }

      IAlgorithm_sptr etConv = this->createChildAlgorithm("DgsConvertToEnergyTransfer");
      etConv->setProperty("InputWorkspace", sampleWS);
      etConv->setProperty("InputMonitorWorkspace", sampleMonWS);
      etConv->setProperty("IntegratedDetectorVanadium", idetVanWS);
      const double ei = this->getProperty("IncidentEnergyGuess");
      etConv->setProperty("IncidentEnergyGuess", ei);
      if (!maskWS && hardMaskWS)
      {
        maskWS = hardMaskWS;
      }
      etConv->setProperty("MaskWorkspace", maskWS);
      if (groupingWS)
      {
        etConv->setProperty("GroupingWorkspace", groupingWS);
      }
      etConv->setProperty("ReductionProperties", reductionManagerName);
      std::string tibWsName = this->getPropertyValue("OutputWorkspace") + "_tib";
      etConv->executeAsChildAlg();
      outputWS = etConv->getProperty("OutputWorkspace");
      MatrixWorkspace_sptr tibWS = etConv->getProperty("OutputTibWorkspace");

      if (tibWS && showIntermedWS)
      {
        this->declareProperty(new WorkspaceProperty<>("SampleTibWorkspace",
            tibWsName, Direction::Output));
        this->setProperty("SampleTibWorkspace", tibWS);
      }

      Workspace_sptr absSampleWS = this->loadInputData("AbsUnitsSample", false);

      // Perform absolute normalisation if necessary
      if (absSampleWS)
      {
        std::string absWsName = outputWsName + "_absunits";

        // Collect the other workspaces first.
        MatrixWorkspace_sptr absSampleMonWS = this->getProperty("AbsUnitsSampleInputMonitorWorkspace");
        Workspace_sptr absDetVanWS = this->loadInputData("AbsUnitsDetectorVanadium", false);
        MatrixWorkspace_sptr absDetVanMonWS = this->getProperty("AbsUnitsDetectorVanadiumInputMonitorWorkspace");
        MatrixWorkspace_sptr absGroupingWS = this->loadGroupingFile("AbsUnits");

        // Run the absolute normalisation reduction
        IAlgorithm_sptr absUnitsRed = this->createChildAlgorithm("DgsAbsoluteUnitsReduction");
        absUnitsRed->setProperty("InputWorkspace", absSampleWS);
        absUnitsRed->setProperty("InputMonitorWorkspace", absSampleMonWS);
        absUnitsRed->setProperty("DetectorVanadiumWorkspace", absDetVanWS);
        absUnitsRed->setProperty("DetectorVanadiumMonitorWorkspace",
            absDetVanMonWS);
        absUnitsRed->setProperty("GroupingWorkspace", absGroupingWS);
        absUnitsRed->setProperty("MaskWorkspace", maskWS);
        absUnitsRed->setProperty("ReductionProperties", reductionManagerName);
        absUnitsRed->executeAsChildAlg();
        MatrixWorkspace_sptr absUnitsWS = absUnitsRed->getProperty("OutputWorkspace");
//!!! There is Property outputMaskWorkspace to get masks? It looks like one is using wrong property for masks
        MatrixWorkspace_sptr absMaskWS = absUnitsRed->getProperty("OutputWorkspace");

        IAlgorithm_sptr mask = this->createChildAlgorithm("MaskDetectors");
        mask->setProperty("Workspace", outputWS);
        mask->setProperty("MaskedWorkspace", absMaskWS);
        mask->executeAsChildAlg();
        outputWS = mask->getProperty("Workspace");

        // Do absolute normalisation
        outputWS = divide(outputWS, absUnitsWS);

        if (showIntermedWS)
        {
          this->declareProperty(new WorkspaceProperty<>("AbsUnitsWorkspace",
              absWsName, Direction::Output));
          this->setProperty("AbsUnitsWorkspace", absUnitsWS);
          this->declareProperty(new WorkspaceProperty<>("AbsUnitsDiagMask",
              outputWsName+"_absunits_diagmask", Direction::Output));
          this->setProperty("AbsUnitsDiagMask", absMaskWS);
        }
      }

      // Convert from DeltaE to powder S(Q,W)
      const bool doPowderConvert = this->getProperty("DoPowderDataConversion");
      if (doPowderConvert)
      {
        g_log.notice() << "Converting to powder S(Q,W)" << std::endl;
        // Collect information
        std::string sqwWsName = outputWsName + "_pd_sqw";
        std::vector<double> qBinning = this->getProperty("PowderMomTransferRange");
        const double initialEnergy = boost::lexical_cast<double>(outputWS->run().getProperty("Ei")->value());

        IAlgorithm_sptr sofqw = this->createChildAlgorithm("SofQW3");
        sofqw->setProperty("InputWorkspace", outputWS);
        sofqw->setProperty("QAxisBinning", qBinning);
        sofqw->setProperty("EMode", "Direct");
        sofqw->setProperty("EFixed", initialEnergy);
        sofqw->executeAsChildAlg();
        MatrixWorkspace_sptr sqwWS = sofqw->getProperty("OutputWorkspace");
        this->declareProperty(new WorkspaceProperty<>("PowderSqwWorkspace",
            sqwWsName, Direction::Output));
        this->setProperty("PowderSqwWorkspace", sqwWS);

        const bool saveProcNexus = this->getProperty("SavePowderNexusFile");
        if (saveProcNexus)
        {
          std::string saveProcNexusFilename = this->getProperty("SavePowderNexusFilename");
          if (saveProcNexusFilename.empty())
          {
            saveProcNexusFilename = sqwWsName + ".nxs";
          }
          IAlgorithm_sptr saveNxs = this->createChildAlgorithm("SaveNexus");
          saveNxs->setProperty("InputWorkspace", sqwWS);
          saveNxs->setProperty("Filename", saveProcNexusFilename);
          saveNxs->executeAsChildAlg();
        }
      }

      this->setProperty("OutputWorkspace", outputWS);
    }
Example #14
0
/** Executes the algorithm. 
 * 
 *  @throw std::runtime_error Thrown with Workspace problems
 */
void RotateInstrumentComponent::exec()
{
  // Get the workspace
  MatrixWorkspace_sptr WS = getProperty("Workspace");
  const std::string ComponentName = getProperty("ComponentName");
  const int DetID = getProperty("DetectorID");
  const double X = getProperty("X");
  const double Y = getProperty("Y");
  const double Z = getProperty("Z");
  const double angle = getProperty("Angle");
  const bool RelativeRotation = getProperty("RelativeRotation");

  if (X + Y + Z == 0.0) throw std::invalid_argument("The rotation axis must not be a zero vector");

  Instrument_const_sptr inst = WS->getInstrument();
  IComponent_const_sptr comp;

  // Find the component to move
  if (DetID != -1)
  {
      comp = inst->getDetector(DetID);
      if (comp == 0)
      {
          std::ostringstream mess;
          mess<<"Detector with ID "<<DetID<<" was not found.";
          g_log.error(mess.str());
          throw std::runtime_error(mess.str());
      }
  }
  else if (!ComponentName.empty())
  {
      comp = inst->getComponentByName(ComponentName);
      if (comp == 0)
      {
          std::ostringstream mess;
          mess<<"Component with name "<<ComponentName<<" was not found.";
          g_log.error(mess.str());
          throw std::runtime_error(mess.str());
      }
  }
  else
  {
      g_log.error("DetectorID or ComponentName must be given.");
      throw std::invalid_argument("DetectorID or ComponentName must be given.");
  }

  // First set new relative or absolute rotation
  Quat Rot;
  if (RelativeRotation)
  {
      Quat Rot0 = comp->getRelativeRot();
      Rot = Rot0 * Quat(angle,V3D(X,Y,Z));
  }
  else
  {
      Rot = Quat(angle,V3D(X,Y,Z));
      // Then find the corresponding relative position
      boost::shared_ptr<const IComponent> parent = comp->getParent();
      if (parent)
      {
          Quat rot0 = parent->getRelativeRot();
          rot0.inverse();
          Rot = Rot * rot0;
      }
  }

  //Need to get the address to the base instrument component
  Geometry::ParameterMap& pmap = WS->instrumentParameters();
  // Add a parameter for the new rotation
  pmap.addQuat(comp.get(), "rot", Rot);

  return;
}
Example #15
0
void SavePAR::exec() {
 
  // Get the input workspace
  MatrixWorkspace_sptr inputWorkspace = getProperty("InputWorkspace");

  // Get the sample position
  const Kernel::V3D samplePos =
      inputWorkspace->getInstrument()->getSample()->getPos();

  // Retrieve the filename from the properties
  const std::string filename = getProperty("Filename");

  // Get a pointer to the sample
  IObjComponent_const_sptr sample =
      inputWorkspace->getInstrument()->getSample();

  std::ofstream outPAR_file(filename.c_str());

  if (!outPAR_file) {
    g_log.error("Failed to open (PAR) file:" + filename);
    throw Kernel::Exception::FileError("Failed to open (PAR) file:",
        filename);
  }

   // execute the subalgorithm to calculate the detector's parameters;
       IAlgorithm_sptr   spCalcDetPar = this->createSubAlgorithm("FindDetectorsPar", 0, 1, true, 1);
       spCalcDetPar->initialize();
       spCalcDetPar->setPropertyValue("InputWorkspace", inputWorkspace->getName());
       // calculate linear rather then angular detector's sizes;
       spCalcDetPar->setPropertyValue("ReturnLinearRanges", "1");
       // in test mode, request the subalgortithm to create output workspace and add it to dataservice
       if(!det_par_ws_name.empty()){
           spCalcDetPar->setPropertyValue("OutputParTable",det_par_ws_name);
       }
  
        // let's not do this for the time being
 /* std::string parFileName = this->getPropertyValue("ParFile");
     if(!(parFileName.empty()||parFileName=="not_used.par")){
               spCalcDetPar->setPropertyValue("ParFile",parFileName);
                   }*/
      spCalcDetPar->execute();
      //
     FindDetectorsPar * pCalcDetPar = dynamic_cast<FindDetectorsPar *>(spCalcDetPar.get());
     if(!pCalcDetPar){	  // "can not get pointer to FindDetectorsPar algorithm"
          throw(std::bad_cast());
      }
      const std::vector<double> & azimuthal           = pCalcDetPar->getAzimuthal();
      const std::vector<double> & polar               = pCalcDetPar->getPolar();
      const std::vector<double> & azimuthal_width     = pCalcDetPar->getAzimWidth();
      const std::vector<double> & polar_width         = pCalcDetPar->getPolarWidth();
      const std::vector<double> & secondary_flightpath= pCalcDetPar->getFlightPath();
      const std::vector<size_t> & det_ID              = pCalcDetPar->getDetID();


      size_t nDetectors = pCalcDetPar->getNDetectors();

  
   // Write the number of detectors to the file.
     outPAR_file <<" "<< nDetectors << std::endl;

   for (size_t i = 0; i < nDetectors; ++i) {
    // verify if no detector defined;
    volatile double NanID = azimuthal[i];
    if(NanID !=azimuthal[i] )continue; // skip NaN -s

      // Now write all the detector info.
      outPAR_file << std::fixed << std::setprecision(3);
      outPAR_file.width(10);
      outPAR_file <<secondary_flightpath[i];
      outPAR_file.width(10);
      outPAR_file<< polar[i];
      outPAR_file.width(10);
      outPAR_file << (-azimuthal[i]);
      outPAR_file.width(10);
      outPAR_file << polar_width[i];
      outPAR_file.width(10);
      outPAR_file << azimuthal_width[i];
      outPAR_file.width(10);
      outPAR_file << det_ID[i] << std::endl;

  }

  // Close the file
  outPAR_file.close();
}
/** Execute the algorithm.
 */
void ConvertToDetectorFaceMD::exec() {
  // TODO convert matrix to event as needed
  MatrixWorkspace_sptr mws = this->getProperty("InputWorkspace");

  in_ws = boost::dynamic_pointer_cast<EventWorkspace>(mws);
  if (!in_ws)
    throw std::runtime_error("InputWorkspace is not an EventWorkspace");

  // Fill the map, throw if there are grouped pixels.
  m_detID_to_WI =
      in_ws->getDetectorIDToWorkspaceIndexVector(m_detID_to_WI_offset, true);

  // Get the map of the banks we'll display
  std::map<int, RectangularDetector_const_sptr> banks = this->getBanks();

  // Find the size in the TOF dimension
  double tof_min, tof_max;
  Axis *ax0 = in_ws->getAxis(0);
  in_ws->getXMinMax(tof_min, tof_max);
  if (ax0->getValue(0) < tof_min)
    tof_min = ax0->getValue(0);
  if (ax0->getValue(ax0->length() - 1) > tof_max)
    tof_max = ax0->getValue(ax0->length() - 1);

  // Get MDFrame of General Frame type
  Mantid::Geometry::GeneralFrame framePixel(
      Mantid::Geometry::GeneralFrame::GeneralFrameName, "pixel");
  Mantid::Geometry::GeneralFrame frameTOF(
      Mantid::Geometry::GeneralFrame::GeneralFrameName, ax0->unit()->label());

  // ------------------ Build all the dimensions ----------------------------
  MDHistoDimension_sptr dimX(
      new MDHistoDimension("x", "x", framePixel, static_cast<coord_t>(0),
                           static_cast<coord_t>(m_numXPixels), m_numXPixels));
  MDHistoDimension_sptr dimY(
      new MDHistoDimension("y", "y", framePixel, static_cast<coord_t>(0),
                           static_cast<coord_t>(m_numYPixels), m_numYPixels));
  std::string TOFname = ax0->title();
  if (TOFname.empty())
    TOFname = ax0->unit()->unitID();
  MDHistoDimension_sptr dimTOF(new MDHistoDimension(
      TOFname, TOFname, frameTOF, static_cast<coord_t>(tof_min),
      static_cast<coord_t>(tof_max), ax0->length()));

  std::vector<IMDDimension_sptr> dims{dimX, dimY, dimTOF};

  if (banks.size() > 1) {
    Mantid::Geometry::GeneralFrame frameNumber(
        Mantid::Geometry::GeneralFrame::GeneralFrameName, "number");
    int min = banks.begin()->first;
    int max = banks.rbegin()->first + 1;
    MDHistoDimension_sptr dimBanks(new MDHistoDimension(
        "bank", "bank", frameNumber, static_cast<coord_t>(min),
        static_cast<coord_t>(max), max - min));
    dims.push_back(dimBanks);
  }

  // --------- Create the workspace with the right number of dimensions
  // ----------
  size_t nd = dims.size();
  IMDEventWorkspace_sptr outWS =
      MDEventFactory::CreateMDWorkspace(nd, "MDEvent");
  outWS->initGeometry(dims);
  outWS->initialize();
  this->setBoxController(outWS->getBoxController(), mws->getInstrument());
  outWS->splitBox();

  MDEventWorkspace3::sptr outWS3 =
      boost::dynamic_pointer_cast<MDEventWorkspace3>(outWS);
  MDEventWorkspace4::sptr outWS4 =
      boost::dynamic_pointer_cast<MDEventWorkspace4>(outWS);

  // Copy ExperimentInfo (instrument, run, sample) to the output WS
  ExperimentInfo_sptr ei(in_ws->cloneExperimentInfo());
  uint16_t runIndex = outWS->addExperimentInfo(ei);

  // ---------------- Convert each bank --------------------------------------
  for (auto &bank : banks) {
    int bankNum = bank.first;
    RectangularDetector_const_sptr det = bank.second;
    for (int x = 0; x < det->xpixels(); x++)
      for (int y = 0; y < det->ypixels(); y++) {
        // Find the workspace index for this pixel coordinate
        detid_t detID = det->getDetectorIDAtXY(x, y);
        size_t wi = m_detID_to_WI[detID + m_detID_to_WI_offset];
        if (wi >= in_ws->getNumberHistograms())
          throw std::runtime_error("Invalid workspace index found in bank " +
                                   det->getName() + "!");

        coord_t xPos = static_cast<coord_t>(x);
        coord_t yPos = static_cast<coord_t>(y);
        coord_t bankPos = static_cast<coord_t>(bankNum);

        EventList &el = in_ws->getSpectrum(wi);

        // We want to bind to the right templated function, so we have to know
        // the type of TofEvent contained in the EventList.
        boost::function<void()> func;
        switch (el.getEventType()) {
        case TOF:
          if (nd == 3)
            this->convertEventList<TofEvent, MDEvent<3>, 3>(
                outWS3, wi, xPos, yPos, bankPos, runIndex, detID);
          else if (nd == 4)
            this->convertEventList<TofEvent, MDEvent<4>, 4>(
                outWS4, wi, xPos, yPos, bankPos, runIndex, detID);
          break;
        case WEIGHTED:
          if (nd == 3)
            this->convertEventList<WeightedEvent, MDEvent<3>, 3>(
                outWS3, wi, xPos, yPos, bankPos, runIndex, detID);
          else if (nd == 4)
            this->convertEventList<WeightedEvent, MDEvent<4>, 4>(
                outWS4, wi, xPos, yPos, bankPos, runIndex, detID);
          break;
        case WEIGHTED_NOTIME:
          if (nd == 3)
            this->convertEventList<WeightedEventNoTime, MDEvent<3>, 3>(
                outWS3, wi, xPos, yPos, bankPos, runIndex, detID);
          else if (nd == 4)
            this->convertEventList<WeightedEventNoTime, MDEvent<4>, 4>(
                outWS4, wi, xPos, yPos, bankPos, runIndex, detID);
          break;
        default:
          throw std::runtime_error("EventList had an unexpected data type!");
        }
      }
  }

  // ---------------------- Perform all box splitting ---------------
  ThreadScheduler *ts = new ThreadSchedulerLargestCost();
  ThreadPool tp(ts);
  outWS->splitAllIfNeeded(ts);
  tp.joinAll();
  outWS->refreshCache();

  // Save the output workspace
  this->setProperty("OutputWorkspace", outWS);
}
Example #17
0
/**
 * Mask edges of a RectangularDetector
 * @param ws :: Input workspace
 * @param left :: number of columns to mask left
 * @param right :: number of columns to mask right
 * @param high :: number of rows to mask top
 * @param low :: number of rows to mask Bottom
 * @param componentName :: Must be a RectangularDetector
 */
void CalculateEfficiency::maskEdges(MatrixWorkspace_sptr ws, int left,
                                    int right, int high, int low,
                                    const std::string &componentName) {

  auto instrument = ws->getInstrument();

  boost::shared_ptr<Mantid::Geometry::RectangularDetector> component;
  try {
    component =
        boost::const_pointer_cast<Mantid::Geometry::RectangularDetector>(
            boost::dynamic_pointer_cast<
                const Mantid::Geometry::RectangularDetector>(
                instrument->getComponentByName(componentName)));
  } catch (std::exception &) {
    g_log.warning("Expecting the component " + componentName +
                  " to be a RectangularDetector. maskEdges not executed.");
    return;
  }
  if (!component) {
    g_log.warning("Component " + componentName +
                  " is not a RectangularDetector. MaskEdges not executed.");
    return;
  }

  std::vector<int> IDs;
  int i = 0;

  while (i < left * component->idstep()) {
    IDs.push_back(component->idstart() + i);
    i += 1;
  }
  // right
  i = component->maxDetectorID() - right * component->idstep();
  while (i < component->maxDetectorID()) {
    IDs.push_back(i);
    i += 1;
  }
  // low: 0,256,512,768,..,1,257,513
  for (int row = 0; row < low; row++) {
    i = row + component->idstart();
    while (i < component->nelements() * component->idstep() -
                   component->idstep() + low + component->idstart()) {
      IDs.push_back(i);
      i += component->idstep();
    }
  }
  // high # 255, 511, 767..
  for (int row = 0; row < high; row++) {
    i = component->idstep() + component->idstart() - row - 1;
    while (i < component->nelements() * component->idstep() +
                   component->idstart()) {
      IDs.push_back(i);
      i += component->idstep();
    }
  }

  g_log.debug() << "CalculateEfficiency::maskEdges Detector Ids to Mask:"
                << std::endl;
  for (auto id : IDs) {
    g_log.debug() << id << " ";
  }
  g_log.debug() << std::endl;

  IAlgorithm_sptr maskAlg = createChildAlgorithm("MaskDetectors");
  maskAlg->setChild(true);
  maskAlg->setProperty("Workspace", ws);
  maskAlg->setProperty("DetectorList", IDs);
  maskAlg->execute();
}
Example #18
0
  /** Reads the header of a .peaks file
   * @param outWS :: the workspace in which to place the information
   * @param in :: stream of the input file
   * @param T0 :: Time offset
   * @return the first word on the next line
   */
  std::string LoadIsawPeaks::readHeader( PeaksWorkspace_sptr outWS, std::ifstream& in, double &T0 )
  {
    std::string tag;
    std::string r = getWord( in ,  false );

    if( r.length() < 1 )
      throw std::logic_error( std::string( "No first line of Peaks file" ) );

    if( r.compare( std::string( "Version:" ) ) != 0 )
      throw std::logic_error(
          std::string( "No Version: on first line of Peaks file" ) );

    std::string C_version = getWord( in ,  false );
    if( C_version.length() < 1 )
      throw  std::logic_error( std::string( "No Version for Peaks file" ) );

    getWord( in ,  false ); //tag
    // cppcheck-suppress unreadVariable
    std::string C_Facility = getWord( in ,  false );

    getWord( in ,  false ); //tag
    std::string C_Instrument = getWord( in ,  false );

    if( C_Instrument.length() < 1 )
      throw std::logic_error(
          std::string( "No Instrument for Peaks file" ) );

    // Date: use the current date/time if not found
    Kernel::DateAndTime C_experimentDate;
    std::string date;
    tag = getWord( in ,  false );
    if(tag.empty())
      date = Kernel::DateAndTime::getCurrentTime().toISO8601String();
    else if(tag == "Date:")
      date = getWord( in ,  false );
    readToEndOfLine( in ,  true );

    // Now we load the instrument using the name and date
    MatrixWorkspace_sptr tempWS = WorkspaceFactory::Instance().create("Workspace2D", 1, 1, 1);
    tempWS->mutableRun().addProperty<std::string>("run_start", date);

    IAlgorithm_sptr loadInst= createChildAlgorithm("LoadInstrument");
    loadInst->setPropertyValue("InstrumentName", C_Instrument);
    loadInst->setProperty<MatrixWorkspace_sptr> ("Workspace", tempWS);
    loadInst->executeAsChildAlg();

    // Populate the instrument parameters in this workspace - this works around a bug
    tempWS->populateInstrumentParameters();
    Geometry::Instrument_const_sptr instr_old = tempWS->getInstrument() ;
    boost::shared_ptr< ParameterMap > map(new ParameterMap());
    Geometry::Instrument_const_sptr instr ( new Geometry::Instrument(instr_old->baseInstrument(), map ));

    //std::string s;
    std::string  s = ApplyCalibInfo(in, "", instr_old, instr, T0);
    outWS->setInstrument( instr);

    // Now skip all lines on L1, detector banks, etc. until we get to a block of peaks. They start with 0.
   // readToEndOfLine( in ,  true );
   // readToEndOfLine( in ,  true );
   // s = getWord(in, false);
    while (s != "0" && in.good())
    {
      readToEndOfLine( in ,  true );
      s = getWord(in, false);
    }


    return s;
  }
Example #19
0
void ModeratorTzero::exec()
{
  m_tolTOF = getProperty("tolTOF"); //Tolerance in the calculation of the emission time, in microseconds
  m_niter=getProperty("Niter"); // number of iterations
  const MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
  m_instrument = inputWS->getInstrument(); // pointer to the instrument

  //deltaE-mode (should be "indirect")
  std::vector<std::string> Emode=m_instrument->getStringParameter("deltaE-mode");
  if(Emode.empty())
    throw Exception::InstrumentDefinitionError("Unable to retrieve instrument geometry (direct or indirect) parameter", inputWS->getTitle());
  if(Emode[0]!= "indirect")
    throw Exception::InstrumentDefinitionError("Instrument geometry must be of type indirect.");

  // extract formula from instrument parameters
  std::vector<std::string> t0_formula=m_instrument->getStringParameter("t0_formula");
  if(t0_formula.empty()) throw Exception::InstrumentDefinitionError("Unable to retrieve t0_formula among instrument parameters");
  m_formula=t0_formula[0];

  //Run execEvent if eventWorkSpace
  EventWorkspace_const_sptr eventWS = boost::dynamic_pointer_cast<const EventWorkspace>(inputWS);
  if (eventWS != NULL)
  {
    execEvent();
    return;
  }

  MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace");
  //Check whether input == output to see whether a new workspace is required.
  if ( outputWS != inputWS )
  {
    //Create new workspace for output from old
    outputWS = WorkspaceFactory::Instance().create(inputWS);
  }

  const size_t numHists = static_cast<size_t>(inputWS->getNumberHistograms());
  Progress prog(this,0.0,1.0,numHists); //report progress of algorithm
  PARALLEL_FOR2(inputWS, outputWS)
  // iterate over the spectra
  for (int i=0; i < static_cast<int>(numHists); ++i)
  {
    PARALLEL_START_INTERUPT_REGION
    size_t wsIndex = static_cast<size_t>(i);
    double L1=CalculateL1(inputWS, wsIndex); // distance from source to sample or monitor
    double t2=CalculateT2(inputWS, wsIndex); // time from sample to detector
    // shift the time of flights by the emission time from the moderator
    if(t2 >= 0) //t2 < 0 when no detector info is available
    {
      double E1;  
      mu::Parser parser;
      parser.DefineVar("incidentEnergy", &E1); // associate E1 to this parser
      parser.SetExpr(m_formula);
      E1=m_convfactor*(L1/m_t1min)*(L1/m_t1min);
      double min_t0_next=parser.Eval(); // fast neutrons are shifted by min_t0_next, irrespective of tof
      MantidVec &inbins = inputWS->dataX(i);
      MantidVec &outbins = outputWS->dataX(i);

      // iterate over the time-of-flight values
      for(unsigned int ibin=0; ibin < inbins.size(); ibin++)
      {
        double tof=inbins[ibin]; // current time-of-flight
        if(tof<m_t1min+t2)
          tof-=min_t0_next;
        else
          tof-=CalculateT0(tof, L1, t2, E1, parser);
        outbins[ibin] = tof;
      }
    }
    else
    {
      outputWS->dataX(i) = inputWS->dataX(i);
    }
    //Copy y and e data
    outputWS->dataY(i) = inputWS->dataY(i);
    outputWS->dataE(i) = inputWS->dataE(i);
    prog.report();
    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION

  // Copy units
  if (inputWS->getAxis(0)->unit().get())
  {
      outputWS->getAxis(0)->unit() = inputWS->getAxis(0)->unit();
  }
  try
  {
    if(inputWS->getAxis(1)->unit().get())
    {
      outputWS->getAxis(1)->unit() = inputWS->getAxis(1)->unit();
    }
  }
  catch(Exception::IndexError &) {
    // OK, so this isn't a Workspace2D
  }

  // Assign it to the output workspace property
  setProperty("OutputWorkspace",outputWS);
}
/** Execute the algorithm.
 */
void CreateGroupingWorkspace::exec() {
  MatrixWorkspace_sptr inWS = getProperty("InputWorkspace");
  std::string InstrumentName = getPropertyValue("InstrumentName");
  std::string InstrumentFilename = getPropertyValue("InstrumentFilename");
  std::string OldCalFilename = getPropertyValue("OldCalFilename");
  std::string GroupNames = getPropertyValue("GroupNames");
  std::string grouping = getPropertyValue("GroupDetectorsBy");
  int numGroups = getProperty("FixedGroupCount");
  std::string componentName = getPropertyValue("ComponentName");

  // Some validation
  int numParams = 0;
  if (inWS)
    numParams++;
  if (!InstrumentName.empty())
    numParams++;
  if (!InstrumentFilename.empty())
    numParams++;

  if (numParams > 1)
    throw std::invalid_argument("You must specify exactly ONE way to get an "
                                "instrument (workspace, instrument name, or "
                                "IDF file). You specified more than one.");
  if (numParams == 0)
    throw std::invalid_argument("You must specify exactly ONE way to get an "
                                "instrument (workspace, instrument name, or "
                                "IDF file). You specified none.");

  if (!OldCalFilename.empty() && !GroupNames.empty())
    throw std::invalid_argument("You must specify either to use the "
                                "OldCalFilename parameter OR GroupNames but "
                                "not both!");

  bool sortnames = false;

  // ---------- Get the instrument one of 3 ways ---------------------------
  Instrument_const_sptr inst;
  if (inWS) {
    inst = inWS->getInstrument();
  } else {
    Algorithm_sptr childAlg = createChildAlgorithm("LoadInstrument", 0.0, 0.2);
    MatrixWorkspace_sptr tempWS = boost::make_shared<Workspace2D>();
    childAlg->setProperty<MatrixWorkspace_sptr>("Workspace", tempWS);
    childAlg->setPropertyValue("Filename", InstrumentFilename);
    childAlg->setProperty("RewriteSpectraMap",
                          Mantid::Kernel::OptionalBool(true));
    childAlg->setPropertyValue("InstrumentName", InstrumentName);
    childAlg->executeAsChildAlg();
    inst = tempWS->getInstrument();
  }

  if (GroupNames.empty() && OldCalFilename.empty()) {
    if (grouping.compare("All") == 0) {
      GroupNames = inst->getName();
    } else if (inst->getName().compare("SNAP") == 0 &&
               grouping.compare("Group") == 0) {
      GroupNames = "East,West";
    } else {
      sortnames = true;
      GroupNames = "";
      int maxRecurseDepth = this->getProperty("MaxRecursionDepth");

      // cppcheck-suppress syntaxError
          PRAGMA_OMP(parallel for schedule(dynamic, 1) )
          for (int num = 0; num < 300; ++num) {
            PARALLEL_START_INTERUPT_REGION
            std::ostringstream mess;
            mess << grouping << num;
            IComponent_const_sptr comp =
                inst->getComponentByName(mess.str(), maxRecurseDepth);
            PARALLEL_CRITICAL(GroupNames)
            if (comp)
              GroupNames += mess.str() + ",";
            PARALLEL_END_INTERUPT_REGION
          }
          PARALLEL_CHECK_INTERUPT_REGION
    }
  }

  // --------------------------- Create the output --------------------------
  auto outWS = boost::make_shared<GroupingWorkspace>(inst);
  this->setProperty("OutputWorkspace", outWS);

  // This will get the grouping
  std::map<detid_t, int> detIDtoGroup;

  Progress prog(this, 0.2, 1.0, outWS->getNumberHistograms());
  // Make the grouping one of three ways:
  if (!GroupNames.empty())
    detIDtoGroup = makeGroupingByNames(GroupNames, inst, prog, sortnames);
  else if (!OldCalFilename.empty())
    detIDtoGroup = readGroupingFile(OldCalFilename, prog);
  else if ((numGroups > 0) && !componentName.empty())
    detIDtoGroup =
        makeGroupingByNumGroups(componentName, numGroups, inst, prog);

  g_log.information() << detIDtoGroup.size()
                      << " entries in the detectorID-to-group map.\n";
  setProperty("NumberGroupedSpectraResult",
              static_cast<int>(detIDtoGroup.size()));

  if (detIDtoGroup.empty()) {
    g_log.warning() << "Creating empty group workspace\n";
    setProperty("NumberGroupsResult", static_cast<int>(0));
  } else {
    size_t numNotFound = 0;

    // Make the groups, if any
    std::map<detid_t, int>::const_iterator it_end = detIDtoGroup.end();
    std::map<detid_t, int>::const_iterator it;
    std::unordered_set<int> groupCount;
    for (it = detIDtoGroup.begin(); it != it_end; ++it) {
      int detID = it->first;
      int group = it->second;
      groupCount.insert(group);
      try {
        outWS->setValue(detID, double(group));
      } catch (std::invalid_argument &) {
        numNotFound++;
      }
    }
    setProperty("NumberGroupsResult", static_cast<int>(groupCount.size()));

    if (numNotFound > 0)
      g_log.warning() << numNotFound << " detector IDs (out of "
                      << detIDtoGroup.size()
                      << ") were not found in the instrument\n.";
  }
}
void TOFSANSResolutionByPixel::exec() {
  MatrixWorkspace_sptr inWS = getProperty("InputWorkspace");
  double deltaR = getProperty("DeltaR");
  double R1 = getProperty("SourceApertureRadius");
  double R2 = getProperty("SampleApertureRadius");
  const bool doGravity = getProperty("AccountForGravity");

  // Check the input
  checkInput(inWS);

  // Setup outputworkspace
  auto outWS = setupOutputWorkspace(inWS);

  // Convert to meters
  deltaR /= 1000.0;
  R1 /= 1000.0;
  R2 /= 1000.0;

  // The moderator workspace needs to match the data workspace
  // in terms of wavelength binning
  const MatrixWorkspace_sptr sigmaModeratorVSwavelength =
      getModeratorWorkspace(inWS);

  // create interpolation table from sigmaModeratorVSwavelength
  Kernel::Interpolation lookUpTable;

  const auto &xInterpolate = sigmaModeratorVSwavelength->points(0);
  const auto &yInterpolate = sigmaModeratorVSwavelength->y(0);

  // prefer the input to be a pointworkspace and create interpolation function
  if (sigmaModeratorVSwavelength->isHistogramData()) {
    g_log.notice() << "mid-points of SigmaModerator histogram bins will be "
                      "used for interpolation.";
  }

  for (size_t i = 0; i < xInterpolate.size(); ++i) {
    lookUpTable.addPoint(xInterpolate[i], yInterpolate[i]);
  }

  // Calculate the L1 distance
  const V3D samplePos = inWS->getInstrument()->getSample()->getPos();
  const V3D sourcePos = inWS->getInstrument()->getSource()->getPos();
  const V3D SSD = samplePos - sourcePos;
  const double L1 = SSD.norm();

  // Get the collimation length
  double LCollim = getProperty("CollimationLength");

  if (LCollim == 0.0) {
    auto collimationLengthEstimator = SANSCollimationLengthEstimator();
    LCollim = collimationLengthEstimator.provideCollimationLength(inWS);
    g_log.information() << "No collimation length was specified. A default "
                           "collimation length was estimated to be " << LCollim
                        << '\n';
  } else {
    g_log.information() << "The collimation length is  " << LCollim << '\n';
  }

  const int numberOfSpectra = static_cast<int>(inWS->getNumberHistograms());
  Progress progress(this, 0.0, 1.0, numberOfSpectra);

  const auto &spectrumInfo = inWS->spectrumInfo();
  for (int i = 0; i < numberOfSpectra; i++) {
    IDetector_const_sptr det;
    if (!spectrumInfo.hasDetectors(i)) {
      g_log.information() << "Workspace index " << i
                          << " has no detector assigned to it - discarding\n";
      continue;
    }
    // If no detector found or if it's masked or a monitor, skip onto the next
    // spectrum
    if (spectrumInfo.isMonitor(i) || spectrumInfo.isMasked(i))
      continue;

    const double L2 = spectrumInfo.l2(i);
    TOFSANSResolutionByPixelCalculator calculator;
    const double waveLengthIndependentFactor =
        calculator.getWavelengthIndependentFactor(R1, R2, deltaR, LCollim, L2);

    // Multiplicative factor to go from lambda to Q
    // Don't get fooled by the function name...
    const double theta = spectrumInfo.twoTheta(i);
    double sinTheta = sin(0.5 * theta);
    double factor = 4.0 * M_PI * sinTheta;

    const auto &xIn = inWS->x(i);
    const size_t xLength = xIn.size();

    // Gravity correction
    std::unique_ptr<GravitySANSHelper> grav;
    if (doGravity) {
      grav = Kernel::make_unique<GravitySANSHelper>(spectrumInfo, i,
                                                    getProperty("ExtraLength"));
    }

    // Get handles on the outputWorkspace
    auto &yOut = outWS->mutableY(i);
    // for each wavelenght bin of each pixel calculate a q-resolution
    for (size_t j = 0; j < xLength - 1; j++) {
      // use the midpoint of each bin
      const double wl = (xIn[j + 1] + xIn[j]) / 2.0;
      // Calculate q. Alternatively q could be calculated using ConvertUnit
      // If we include a gravity correction we need to adjust sinTheta
      // for each wavelength (in Angstrom)
      if (doGravity) {
        double sinThetaGrav = grav->calcSinTheta(wl);
        factor = 4.0 * M_PI * sinThetaGrav;
      }
      const double q = factor / wl;

      // wavelenght spread from bin assumed to be
      const double sigmaSpreadFromBin = xIn[j + 1] - xIn[j];

      // Get the uncertainty in Q
      auto sigmaQ = calculator.getSigmaQValue(lookUpTable.value(wl),
                                              waveLengthIndependentFactor, q,
                                              wl, sigmaSpreadFromBin, L1, L2);

      // Insert the Q value and the Q resolution into the outputworkspace
      yOut[j] = sigmaQ;
    }
    progress.report("Computing Q resolution");
  }

  // Set the y axis label
  outWS->setYUnitLabel("QResolution");

  setProperty("OutputWorkspace", outWS);
}
/**
 * This extraction strategy gets applied when guides are used to calculate the
 * collimation length. The instrument
 * parameter file contains the information about the number of guides to use.
 * The guide data itself is fetched
 * from the sample logs.
 * @param inOutWS: a matrix workspace
 * @param L1: the distance between sample and source
 * @param collimationLengthCorrection: The correction to get the collimation
 * length
 */
double SANSCollimationLengthEstimator::getCollimationLengthWithGuides(
    MatrixWorkspace_sptr inOutWS, const double L1,
    const double collimationLengthCorrection) const {
  auto lCollim = L1 - collimationLengthCorrection;

  // Make sure we have guide cutoffs
  if (!inOutWS->getInstrument()->hasParameter("guide-cutoff")) {
    throw std::invalid_argument("TOFSANSResolutionByPixel: Could not get a "
                                "GuideCutoff from the instrument");
  }

  // Make sure we have a defined number of guidess
  if (!inOutWS->getInstrument()->hasParameter("number-of-guides")) {
    throw std::invalid_argument(
        "TOFSANSResolutionByPixel: Could not get the number of guides.");
  }

  // Make sure we have a guide increment specified
  if (!inOutWS->getInstrument()->hasParameter(
          "guide-collimation-length-increment")) {
    throw std::invalid_argument(
        "TOFSANSResolutionByPixel: Could not find a guide increment.");
  }

  auto numberOfGuides = static_cast<unsigned int>(
      inOutWS->getInstrument()->getNumberParameter("number-of-guides")[0]);
  auto guideIncrement = inOutWS->getInstrument()->getNumberParameter(
      "guide-collimation-length-increment")[0];

  // Make sure that all guides are there. They are labelled as Guide1, Guide2,
  // Guide3, ...
  // The entry is a numeric TimeSeriesProperty or a numeric entry, if something
  // else then default
  std::vector<double> guideValues;
  for (unsigned int i = 1; i <= numberOfGuides; i++) {
    auto guideName = "Guide" + boost::lexical_cast<std::string>(i);
    if (inOutWS->run().hasProperty(guideName)) {
      auto guideValue = getGuideValue(inOutWS->run().getProperty(guideName));
      guideValues.push_back(guideValue);
    } else {
      throw std::invalid_argument("TOFSANSResolutionByPixel: Mismatch between "
                                  "specified number of Guides and actual "
                                  "Guides.");
    }
  }

  auto guideCutoff =
      inOutWS->getInstrument()->getNumberParameter("guide-cutoff")[0];
  // Go through the guides and check in an alternate manner if the guide is
  // smaller
  // or larger than the cut off value. We start at the last guide and check that
  // it is
  // larger than the cutoff, the next one has to be smaller and so on. For
  // example in pseudocode
  // If Guide5 > 130: LCollim+=2.0 else break;
  // If Guide4 < 130: LCollim+=2.0 else break;
  // If Guide3 > 130: LCollim+=2.0 else break;
  // ...
  unsigned int largerSmallerCounter = 0;
  for (auto it = guideValues.rbegin(); it != guideValues.rend(); ++it) {
    bool guideIsLarger = largerSmallerCounter % 2 == 0;
    if (guideIsLarger && (*it > guideCutoff)) {
      lCollim += guideIncrement;
    } else if (!guideIsLarger && (*it < guideCutoff)) {
      lCollim += guideIncrement;
    } else {
      break;
    }
    largerSmallerCounter++;
  }
  return lCollim;
}
/** Convert a SPICE 2D Det MatrixWorkspace to MDEvents and append to an
 * MDEventWorkspace
 * It is optional to use a virtual instrument or copy from input data workspace
 * @brief ConvertCWSDExpToMomentum::convertSpiceMatrixToMomentumMDEvents
 * @param dataws :: data matrix workspace
 * @param usevirtual :: boolean flag to use virtual instrument
 * @param startdetid :: starting detid for detectors from this workspace mapping
 * to virtual instrument in MDEventWorkspace
 * @param runnumber :: run number for all MDEvents created from this matrix
 * workspace
 */
void ConvertCWSDExpToMomentum::convertSpiceMatrixToMomentumMDEvents(
    MatrixWorkspace_sptr dataws, bool usevirtual, const detid_t &startdetid,
    const int runnumber) {
  // Create transformation matrix from which the transformation is
  Kernel::DblMatrix rotationMatrix;
  setupTransferMatrix(dataws, rotationMatrix);

  g_log.information() << "Before insert new event, output workspace has "
                      << m_outputWS->getNEvents() << "Events.\n";

  // Creates a new instance of the MDEventInserte to output workspace
  MDEventWorkspace<MDEvent<3>, 3>::sptr mdws_mdevt_3 =
      boost::dynamic_pointer_cast<MDEventWorkspace<MDEvent<3>, 3>>(m_outputWS);
  MDEventInserter<MDEventWorkspace<MDEvent<3>, 3>::sptr> inserter(mdws_mdevt_3);

  // Calcualte k_i: it is assumed that all k_i are same for one Pt.
  // number, i.e., one 2D XML file
  Kernel::V3D sourcePos = dataws->getInstrument()->getSource()->getPos();
  Kernel::V3D samplePos = dataws->getInstrument()->getSample()->getPos();
  if (dataws->readX(0).size() != 2)
    throw std::runtime_error(
        "Input matrix workspace has wrong dimension in X-axis.");
  double momentum = 0.5 * (dataws->readX(0)[0] + dataws->readX(0)[1]);
  Kernel::V3D ki = (samplePos - sourcePos) * (momentum / sourcePos.norm());

  g_log.debug() << "Source at " << sourcePos.toString()
                << ", Norm = " << sourcePos.norm()
                << ", momentum = " << momentum << "\n"
                << "k_i = " << ki.toString() << "\n";

  // Go though each spectrum to conver to MDEvent
  size_t numspec = dataws->getNumberHistograms();
  double maxsignal = 0;
  size_t nummdevents = 0;
  for (size_t iws = 0; iws < numspec; ++iws) {
    // Get detector positions and signal
    double signal = dataws->readY(iws)[0];
    // Skip event with 0 signal
    if (signal < 0.001)
      continue;
    double error = dataws->readE(iws)[0];
    Kernel::V3D detpos = dataws->getDetector(iws)->getPos();
    std::vector<Mantid::coord_t> q_sample(3);

    // Calculate Q-sample and new detector ID in virtual instrument.
    Kernel::V3D qlab = convertToQSample(samplePos, ki, detpos, momentum,
                                        q_sample, rotationMatrix);
    detid_t native_detid = dataws->getDetector(iws)->getID();
    detid_t detid = native_detid + startdetid;

    // Insert
    inserter.insertMDEvent(
        static_cast<float>(signal), static_cast<float>(error * error),
        static_cast<uint16_t>(runnumber), detid, q_sample.data());
    updateQRange(q_sample);

    g_log.debug() << "Q-lab = " << qlab.toString() << "\n";
    g_log.debug() << "Insert DetID " << detid << ", signal = " << signal
                  << ", with q_sample = " << q_sample[0] << ", " << q_sample[1]
                  << ", " << q_sample[2] << "\n";

    // Update some statistical inforamtion
    if (signal > maxsignal)
      maxsignal = signal;
    ++nummdevents;
  }

  g_log.information() << "Imported Matrixworkspace: Max. Signal = " << maxsignal
                      << ", Add " << nummdevents << " MDEvents "
                      << "\n";

  // Add experiment info including instrument, goniometer and run number
  ExperimentInfo_sptr expinfo = boost::make_shared<ExperimentInfo>();
  if (usevirtual)
    expinfo->setInstrument(m_virtualInstrument);
  else {
    Geometry::Instrument_const_sptr tmp_inst = dataws->getInstrument();
    expinfo->setInstrument(tmp_inst);
  }
  expinfo->mutableRun().setGoniometer(dataws->run().getGoniometer(), false);
  expinfo->mutableRun().addProperty("run_number", runnumber);
  // Add all the other propertys from original data workspace
  const std::vector<Kernel::Property *> vec_property =
      dataws->run().getProperties();
  for (auto property : vec_property) {
    expinfo->mutableRun().addProperty(property->clone());
  }

  m_outputWS->addExperimentInfo(expinfo);

  return;
}
void TOFSANSResolutionByPixel::exec()
{
  MatrixWorkspace_sptr inOutWS = getProperty("InputWorkspace");
  double deltaR = getProperty("DeltaR");
  double R1 = getProperty("SourceApertureRadius");
  double R2 = getProperty("SampleApertureRadius");
  // Convert to meters
  deltaR /= 1000.0;
  R1 /= 1000.0;
  R2 /= 1000.0;
  const double sigmaModeratorMicroSec = getProperty("SigmaModerator");

  const V3D samplePos = inOutWS->getInstrument()->getSample()->getPos();
  const V3D sourcePos = inOutWS->getInstrument()->getSource()->getPos();
  const V3D SSD = samplePos - sourcePos;
  const double L1 = SSD.norm();

  const int numberOfSpectra = static_cast<int>(inOutWS->getNumberHistograms());
  Progress progress(this,0.0,1.0,numberOfSpectra);

  //PARALLEL_FOR1(inOutWS)
  for (int i = 0; i < numberOfSpectra; i++)
  {
    //PARALLEL_START_INTERUPT_REGION
    IDetector_const_sptr det;
    try {
      det = inOutWS->getDetector(i);
    } catch (Exception::NotFoundError&) {
      g_log.information() << "Spectrum index " << i << " has no detector assigned to it - discarding" << std::endl;
      // Catch if no detector. Next line tests whether this happened - test placed
      // outside here because Mac Intel compiler doesn't like 'continue' in a catch
      // in an openmp block.
    }
    // If no detector found or if it's masked or a monitor, skip onto the next spectrum
    if ( !det || det->isMonitor() || det->isMasked() ) continue;

    // Get the flight path from the sample to the detector pixel
    const V3D scatteredFlightPathV3D = det->getPos() - samplePos; 

    const double L2 = scatteredFlightPathV3D.norm();
    const double Lsum = L1+L2;

    // calculate part that is wavelenght independent
    const double dTheta2 = (4.0 * M_PI * M_PI / 12.0) * 
      ( 3.0*R1*R1/(L1*L1) + 3.0*R2*R2*Lsum*Lsum/(L1*L1*L2*L2) + (deltaR*deltaR)/(L2*L2) );

    // Multiplicative factor to go from lambda to Q
    // Don't get fooled by the function name...
    const double theta = inOutWS->detectorTwoTheta(det);
    const double factor = 4.0 * M_PI * sin( theta/2.0 );

    const MantidVec& xIn = inOutWS->readX(i);
    MantidVec& yIn = inOutWS->dataY(i);
    const size_t xLength = xIn.size();

    for ( size_t j = 0; j < xLength-1; j++)
    {
      // Calculate q. Alternatively q could be calculated using ConvertUnit
      const double wl = (xIn[j+1]+xIn[j])/2.0;
      const double q = factor/wl;

      // calculate wavelenght resolution from moderator and histogram time bin width and
      // convert to from unit of micro-seconds to Aangstrom
      const double sigmaLambda = sigmaModeratorMicroSec*3.9560/(1000.0*Lsum);

      // calculate sigmaQ for a given lambda and pixel
      const double sigmaOverLambdaTimesQ = q*sigmaLambda/wl;
      const double sigmaQ = std::sqrt(dTheta2/(wl*wl)+sigmaOverLambdaTimesQ*sigmaOverLambdaTimesQ);

      // update inout workspace with this sigmaQ
      yIn[j] = sigmaQ;
    }

    progress.report("Computing Q resolution");
    //PARALLEL_END_INTERUPT_REGION
  }

}
Example #25
0
void TOFSANSResolution::exec()
{
  Workspace2D_sptr iqWS = getProperty("InputWorkspace");
  MatrixWorkspace_sptr reducedWS = getProperty("ReducedWorkspace");
  EventWorkspace_sptr reducedEventWS = boost::dynamic_pointer_cast<EventWorkspace>(reducedWS);
  const double min_wl = getProperty("MinWavelength");
  const double max_wl = getProperty("MaxWavelength");
  double pixel_size_x = getProperty("PixelSizeX");
  double pixel_size_y = getProperty("PixelSizeY");
  double R1 = getProperty("SourceApertureRadius");
  double R2 = getProperty("SampleApertureRadius");
  // Convert to meters
  pixel_size_x /= 1000.0;
  pixel_size_y /= 1000.0;
  R1 /= 1000.0;
  R2 /= 1000.0;
  wl_resolution = getProperty("DeltaT");

  // Although we want the 'ReducedWorkspace' to be an event workspace for this algorithm to do
  // anything, we don't want the algorithm to 'fail' if it isn't
  if (!reducedEventWS)
  {
    g_log.warning() << "An Event Workspace is needed to compute dQ. Calculation skipped." << std::endl;
    return;
  }

  // Calculate the output binning
  const std::vector<double> binParams = getProperty("OutputBinning");

  // Count histogram for normalization
  const int xLength = static_cast<int>(iqWS->readX(0).size());
  std::vector<double> XNorm(xLength-1, 0.0);

  // Create workspaces with each component of the resolution for debugging purposes
  MatrixWorkspace_sptr thetaWS = WorkspaceFactory::Instance().create(iqWS);
  declareProperty(new WorkspaceProperty<>("ThetaError","",Direction::Output));
  setPropertyValue("ThetaError","__"+iqWS->getName()+"_theta_error");
  setProperty("ThetaError",thetaWS);
  thetaWS->setX(0,iqWS->readX(0));
  MantidVec& ThetaY = thetaWS->dataY(0);

  MatrixWorkspace_sptr tofWS = WorkspaceFactory::Instance().create(iqWS);
  declareProperty(new WorkspaceProperty<>("TOFError","",Direction::Output));
  setPropertyValue("TOFError","__"+iqWS->getName()+"_tof_error");
  setProperty("TOFError",tofWS);
  tofWS->setX(0,iqWS->readX(0));
  MantidVec& TOFY = tofWS->dataY(0);

  // Initialize Dq
  MantidVec& DxOut = iqWS->dataDx(0);
  for ( int i = 0; i<xLength-1; i++ ) DxOut[i] = 0.0;

  const V3D samplePos = reducedWS->getInstrument()->getSample()->getPos();
  const V3D sourcePos = reducedWS->getInstrument()->getSource()->getPos();
  const V3D SSD = samplePos - sourcePos;
  const double L1 = SSD.norm();

  const int numberOfSpectra = static_cast<int>(reducedWS->getNumberHistograms());
  Progress progress(this,0.0,1.0,numberOfSpectra);

  PARALLEL_FOR2(reducedEventWS, iqWS)
  for (int i = 0; i < numberOfSpectra; i++)
  {
    PARALLEL_START_INTERUPT_REGION
    IDetector_const_sptr det;
    try {
      det = reducedEventWS->getDetector(i);
    } catch (Exception::NotFoundError&) {
      g_log.warning() << "Spectrum index " << i << " has no detector assigned to it - discarding" << std::endl;
      // Catch if no detector. Next line tests whether this happened - test placed
      // outside here because Mac Intel compiler doesn't like 'continue' in a catch
      // in an openmp block.
    }
    // If no detector found or if it's masked or a monitor, skip onto the next spectrum
    if ( !det || det->isMonitor() || det->isMasked() ) continue;

    // Get the flight path from the sample to the detector pixel
    const V3D scattered_flight_path = det->getPos() - samplePos;

    // Multiplicative factor to go from lambda to Q
    // Don't get fooled by the function name...
    const double theta = reducedEventWS->detectorTwoTheta(det);
    const double factor = 4.0 * M_PI * sin( theta/2.0 );

    EventList& el = reducedEventWS->getEventList(i);
    el.switchTo(WEIGHTED);

    std::vector<WeightedEvent>::iterator itev;
    std::vector<WeightedEvent>::iterator itev_end = el.getWeightedEvents().end();

    for (itev = el.getWeightedEvents().begin(); itev != itev_end; ++itev)
    {
      if ( itev->m_weight != itev->m_weight ) continue;
      if (std::abs(itev->m_weight) == std::numeric_limits<double>::infinity()) continue;
      if ( !isEmpty(min_wl) && itev->m_tof < min_wl ) continue;
      if ( !isEmpty(max_wl) && itev->m_tof > max_wl ) continue;

      const double q = factor/itev->m_tof;
      int iq = 0;

      // Bin assignment depends on whether we have log or linear bins
      if(binParams[1]>0.0)
      {
        iq = (int)floor( (q-binParams[0])/ binParams[1] );
      } else {
        iq = (int)floor(log(q/binParams[0])/log(1.0-binParams[1]));
      }

      const double L2 = scattered_flight_path.norm();
      const double src_to_pixel = L1+L2;
      const double dTheta2 = ( 3.0*R1*R1/(L1*L1) + 3.0*R2*R2*src_to_pixel*src_to_pixel/(L1*L1*L2*L2)
            + 2.0*(pixel_size_x*pixel_size_x+pixel_size_y*pixel_size_y)/(L2*L2) )/12.0;

      const double dwl_over_wl = 3.9560*getTOFResolution(itev->m_tof)/(1000.0*(L1+L2)*itev->m_tof);
      const double dq_over_q = std::sqrt(dTheta2/(theta*theta)+dwl_over_wl*dwl_over_wl);

      PARALLEL_CRITICAL(iq)    /* Write to shared memory - must protect */
      if (iq>=0 && iq < xLength-1 && !dq_over_q!=dq_over_q && dq_over_q>0)
      {
        DxOut[iq] += q*dq_over_q*itev->m_weight;
        XNorm[iq] += itev->m_weight;
        TOFY[iq] += q*std::fabs(dwl_over_wl)*itev->m_weight;
        ThetaY[iq] += q*std::sqrt(dTheta2)/theta*itev->m_weight;
      }
    }

    progress.report("Computing Q resolution");
    PARALLEL_END_INTERUPT_REGION
  }
  PARALLEL_CHECK_INTERUPT_REGION
  // Normalize according to the chosen weighting scheme
  for ( int i = 0; i<xLength-1; i++ )
  {
    if (XNorm[i]>0)
    {
      DxOut[i] /= XNorm[i];
      TOFY[i] /= XNorm[i];
      ThetaY[i] /= XNorm[i];
    }
  }
}
void TOFSANSResolutionByPixel::exec() {
  MatrixWorkspace_sptr inOutWS = getProperty("Workspace");
  double deltaR = getProperty("DeltaR");
  double R1 = getProperty("SourceApertureRadius");
  double R2 = getProperty("SampleApertureRadius");
  // Convert to meters
  deltaR /= 1000.0;
  R1 /= 1000.0;
  R2 /= 1000.0;

  const MatrixWorkspace_sptr sigmaModeratorVSwavelength =
      getProperty("SigmaModerator");

  // create interpolation table from sigmaModeratorVSwavelength
  Kernel::Interpolation lookUpTable;

  const MantidVec xInterpolate = sigmaModeratorVSwavelength->readX(0);
  const MantidVec yInterpolate = sigmaModeratorVSwavelength->readY(0);

  // prefer the input to be a pointworkspace and create interpolation function
  if (sigmaModeratorVSwavelength->isHistogramData()) {
    g_log.notice() << "mid-points of SigmaModerator histogram bins will be "
                      "used for interpolation.";

    for (size_t i = 0; i < xInterpolate.size() - 1; ++i) {
      const double midpoint = xInterpolate[i + 1] - xInterpolate[i];
      lookUpTable.addPoint(midpoint, yInterpolate[i]);
    }
  } else {
    for (size_t i = 0; i < xInterpolate.size(); ++i) {
      lookUpTable.addPoint(xInterpolate[i], yInterpolate[i]);
    }
  }

  const V3D samplePos = inOutWS->getInstrument()->getSample()->getPos();
  const V3D sourcePos = inOutWS->getInstrument()->getSource()->getPos();
  const V3D SSD = samplePos - sourcePos;
  const double L1 = SSD.norm();

  const int numberOfSpectra = static_cast<int>(inOutWS->getNumberHistograms());
  Progress progress(this, 0.0, 1.0, numberOfSpectra);

  for (int i = 0; i < numberOfSpectra; i++) {
    IDetector_const_sptr det;
    try {
      det = inOutWS->getDetector(i);
    } catch (Exception::NotFoundError &) {
      g_log.information() << "Spectrum index " << i
                          << " has no detector assigned to it - discarding"
                          << std::endl;
    }
    // If no detector found or if it's masked or a monitor, skip onto the next
    // spectrum
    if (!det || det->isMonitor() || det->isMasked())
      continue;

    // Get the flight path from the sample to the detector pixel
    const V3D scatteredFlightPathV3D = det->getPos() - samplePos;

    const double L2 = scatteredFlightPathV3D.norm();
    const double Lsum = L1 + L2;

    // calculate part that is wavelenght independent
    const double dTheta2 = (4.0 * M_PI * M_PI / 12.0) *
                           (3.0 * R1 * R1 / (L1 * L1) +
                            3.0 * R2 * R2 * Lsum * Lsum / (L1 * L1 * L2 * L2) +
                            (deltaR * deltaR) / (L2 * L2));

    // Multiplicative factor to go from lambda to Q
    // Don't get fooled by the function name...
    const double theta = inOutWS->detectorTwoTheta(det);
    const double factor = 4.0 * M_PI * sin(theta / 2.0);

    const MantidVec &xIn = inOutWS->readX(i);
    MantidVec &yIn = inOutWS->dataY(i);
    const size_t xLength = xIn.size();

    // for each wavelenght bin of each pixel calculate a q-resolution
    for (size_t j = 0; j < xLength - 1; j++) {
      // use the midpoint of each bin
      const double wl = (xIn[j + 1] + xIn[j]) / 2.0;
      // Calculate q. Alternatively q could be calculated using ConvertUnit
      const double q = factor / wl;

      // wavelenght spread from bin assumed to be
      const double sigmaSpreadFromBin = xIn[j + 1] - xIn[j];

      // wavelenght spread from moderatorm, converted from microseconds to
      // wavelengths
      const double sigmaModerator =
          lookUpTable.value(wl) * 3.9560 / (1000.0 * Lsum);

      // calculate wavelenght resolution from moderator and histogram time bin
      const double sigmaLambda =
          std::sqrt(sigmaSpreadFromBin * sigmaSpreadFromBin / 12.0 +
                    sigmaModerator * sigmaModerator);

      // calculate sigmaQ for a given lambda and pixel
      const double sigmaOverLambdaTimesQ = q * sigmaLambda / wl;
      const double sigmaQ = std::sqrt(
          dTheta2 / (wl * wl) + sigmaOverLambdaTimesQ * sigmaOverLambdaTimesQ);

      // update inout workspace with this sigmaQ
      yIn[j] = sigmaQ;
    }

    progress.report("Computing Q resolution");
  }
}
Example #27
0
    /** Executes the algorithm. Reading in the file and creating and populating
     *  the output workspace
     * 
     *  @throw std::runtime_error If the instrument cannot be loaded by the LoadInstrument ChildAlgorithm
     *  @throw InstrumentDefinitionError Thrown if issues with the content of XML instrument file not covered by LoadInstrument
     *  @throw std::invalid_argument If the optional properties are set to invalid values
     */
    void LoadEmptyInstrument::exec()
    {
      // Get other properties
      const double detector_value = getProperty("DetectorValue");
      const double monitor_value = getProperty("MonitorValue");

      // load the instrument into this workspace
      MatrixWorkspace_sptr ws = this->runLoadInstrument();
      Instrument_const_sptr instrument = ws->getInstrument();

      // Get number of detectors stored in instrument
      const size_t number_spectra = instrument->getNumberDetectors();

      // Check that we have some spectra for the workspace
      if( number_spectra == 0){
            g_log.error("Instrument has no detectors, unable to create workspace for it");
            throw Kernel::Exception::InstrumentDefinitionError("No detectors found in instrument");
      }
      
      bool MakeEventWorkspace = getProperty("MakeEventWorkspace");
      
      MatrixWorkspace_sptr outWS;

      if (MakeEventWorkspace)
      {
        //Make a brand new EventWorkspace
        EventWorkspace_sptr localWorkspace = boost::dynamic_pointer_cast<EventWorkspace>(
            API::WorkspaceFactory::Instance().create("EventWorkspace", number_spectra, 2, 1));
        //Copy geometry over.
        API::WorkspaceFactory::Instance().initializeFromParent(ws, localWorkspace, true);

        // Cast to matrix WS
        outWS = boost::dynamic_pointer_cast<MatrixWorkspace>(localWorkspace);
      }
      else
      { 
        // Now create the outputworkspace and copy over the instrument object
        DataObjects::Workspace2D_sptr localWorkspace =
          boost::dynamic_pointer_cast<DataObjects::Workspace2D>(WorkspaceFactory::Instance().create(ws,number_spectra,2,1));

        outWS = boost::dynamic_pointer_cast<MatrixWorkspace>(localWorkspace);
      }

      outWS->rebuildSpectraMapping( true /* include monitors */);


      // ---- Set the values ----------
      if (!MakeEventWorkspace)
      {
        MantidVecPtr x,v,v_monitor;
        x.access().resize(2); x.access()[0]=1.0; x.access()[1]=2.0;
        v.access().resize(1); v.access()[0]=detector_value;
        v_monitor.access().resize(1); v_monitor.access()[0]=monitor_value;

        for (size_t i=0; i < outWS->getNumberHistograms(); i++)
        {
          IDetector_const_sptr det = outWS->getDetector(i);
          if ( det->isMonitor() )
            outWS->setData(i, v_monitor, v_monitor);
          else
            outWS->setData(i, v, v);
        }
      }
      // Save in output
      this->setProperty("OutputWorkspace", outWS);

    }
Example #28
0
  /**
   * Execute the algorithm.
   */
  void SofQW3::exec()
  {
    MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
    // Do the full check for common binning
    if( !WorkspaceHelpers::commonBoundaries(inputWS) )
    {
      throw std::invalid_argument("The input workspace must have common binning across all spectra");
    }

    RebinnedOutput_sptr outputWS = this->setUpOutputWorkspace(inputWS,
                                                 getProperty("QAxisBinning"),
                                                              m_Qout);
    g_log.debug() << "Workspace type: " << outputWS->id() << std::endl;
    setProperty("OutputWorkspace", outputWS);
    const size_t nEnergyBins = inputWS->blocksize();
    const size_t nHistos = inputWS->getNumberHistograms();

    // Progress reports & cancellation
    const size_t nreports(nHistos * nEnergyBins);
    m_progress = boost::shared_ptr<API::Progress>(new API::Progress(this, 0.0,
                                                                    1.0,
                                                                    nreports));

    // Compute input caches
    this->initCachedValues(inputWS);

    std::vector<double> par = inputWS->getInstrument()->getNumberParameter("detector-neighbour-offset");
    if (par.empty())
    {
      // Index theta cache
      this->initThetaCache(inputWS);
    }
    else
    {
      g_log.debug() << "Offset: " << par[0] << std::endl;
      this->m_detNeighbourOffset = static_cast<int>(par[0]);
      this->getValuesAndWidths(inputWS);
    }

    const MantidVec & X = inputWS->readX(0);

    PARALLEL_FOR2(inputWS, outputWS)
    for (int64_t i = 0; i < static_cast<int64_t>(nHistos); ++i) // signed for openmp
    {
      PARALLEL_START_INTERUPT_REGION

      DetConstPtr detector = inputWS->getDetector(i);
      if (detector->isMasked() || detector->isMonitor())
      {
        continue;
      }

      double theta = this->m_theta[i];
      double phi = 0.0;
      double thetaWidth = 0.0;
      double phiWidth = 0.0;
      // Non-PSD mode
      if (par.empty())
      {
        thetaWidth = this->m_thetaWidth;
      }
      // PSD mode
      else
      {
        phi = this->m_phi[i];
        thetaWidth = this->m_thetaWidths[i];
        phiWidth = this->m_phiWidths[i];
      }

      double thetaHalfWidth = 0.5 * thetaWidth;
      double phiHalfWidth = 0.5 * phiWidth;

      const double thetaLower = theta - thetaHalfWidth;
      const double thetaUpper = theta + thetaHalfWidth;

      const double phiLower = phi - phiHalfWidth;
      const double phiUpper = phi + phiHalfWidth;

      const double efixed = this->getEFixed(detector);

      for(size_t j = 0; j < nEnergyBins; ++j)
      {
        m_progress->report("Computing polygon intersections");
        // For each input polygon test where it intersects with
        // the output grid and assign the appropriate weights of Y/E
        const double dE_j = X[j];
        const double dE_jp1 = X[j+1];

        const V2D ll(dE_j, this->calculateQ(efixed, dE_j, thetaLower, phiLower));
        const V2D lr(dE_jp1, this->calculateQ(efixed, dE_jp1, thetaLower, phiLower));
        const V2D ur(dE_jp1, this->calculateQ(efixed, dE_jp1, thetaUpper, phiUpper));
        const V2D ul(dE_j, this->calculateQ(efixed, dE_j, thetaUpper, phiUpper));
        Quadrilateral inputQ = Quadrilateral(ll, lr, ur, ul);

        this->rebinToFractionalOutput(inputQ, inputWS, i, j, outputWS, m_Qout);
      }

      PARALLEL_END_INTERUPT_REGION
    }
    PARALLEL_CHECK_INTERUPT_REGION

    outputWS->finalize();
    this->normaliseOutput(outputWS, inputWS);
  }
Example #29
0
/** Execute the algorithm.
 */
void EditInstrumentGeometry::exec() {
  // Lots of things have to do with the input workspace
  MatrixWorkspace_sptr workspace = getProperty("Workspace");
  Geometry::Instrument_const_sptr originstrument = workspace->getInstrument();

  // Get and check the primary flight path
  double l1 = this->getProperty("PrimaryFlightPath");
  if (isEmpty(l1)) {
    // Use the original L1
    if (!originstrument) {
      std::string errmsg(
          "It is not supported that L1 is not given, ",
          "while there is no instrument associated to input workspace.");
      g_log.error(errmsg);
      throw std::runtime_error(errmsg);
    }
    Geometry::IComponent_const_sptr source = originstrument->getSource();
    Geometry::IComponent_const_sptr sample = originstrument->getSample();
    l1 = source->getDistance(*sample);
    g_log.information() << "Retrieve L1 from input data workspace. \n";
  }
  g_log.information() << "Using L1 = " << l1 << "\n";

  // Get spectra number in case they are in a funny order
  std::vector<int32_t> specids = this->getProperty("SpectrumIDs");
  if (specids.empty()) // they are using the order of the input workspace
  {
    size_t numHist = workspace->getNumberHistograms();
    for (size_t i = 0; i < numHist; ++i) {
      specids.push_back(workspace->getSpectrum(i).getSpectrumNo());
      g_log.information() << "Add spectrum "
                          << workspace->getSpectrum(i).getSpectrumNo() << ".\n";
    }
  }

  // Get the detector ids - empsy means ignore it
  const vector<int> vec_detids = getProperty("DetectorIDs");
  const bool renameDetID(!vec_detids.empty());

  // Get individual detector geometries ordered by input spectrum Numbers
  const std::vector<double> l2s = this->getProperty("L2");
  const std::vector<double> tths = this->getProperty("Polar");
  std::vector<double> phis = this->getProperty("Azimuthal");

  // empty list of L2 and 2-theta is not allowed
  if (l2s.empty()) {
    throw std::runtime_error("User must specify L2 for all spectra. ");
  }
  if (tths.empty()) {
    throw std::runtime_error("User must specify 2theta for all spectra.");
  }

  // empty list of phi means that they are all zero
  if (phis.empty()) {
    phis.assign(l2s.size(), 0.);
  }

  // Validate
  for (size_t ib = 0; ib < l2s.size(); ib++) {
    g_log.information() << "Detector " << specids[ib] << "  L2 = " << l2s[ib]
                        << "  2Theta = " << tths[ib] << '\n';
    if (specids[ib] < 0) {
      // Invalid spectrum Number : less than 0.
      stringstream errmsgss;
      errmsgss << "Detector ID = " << specids[ib] << " cannot be less than 0.";
      throw std::invalid_argument(errmsgss.str());
    }
    if (l2s[ib] <= 0.0) {
      throw std::invalid_argument("L2 cannot be less or equal to 0");
    }
  }

  // Keep original instrument and set the new instrument, if necessary
  const auto spec2indexmap = workspace->getSpectrumToWorkspaceIndexMap();

  // ??? Condition: spectrum has 1 and only 1 detector
  size_t nspec = workspace->getNumberHistograms();

  // Initialize another set of L2/2-theta/Phi/DetectorIDs vector ordered by
  // workspace index
  std::vector<double> storL2s(nspec, 0.);
  std::vector<double> stor2Thetas(nspec, 0.);
  std::vector<double> storPhis(nspec, 0.);
  vector<int> storDetIDs(nspec, 0);

  // Map the properties from spectrum Number to workspace index
  for (size_t i = 0; i < specids.size(); i++) {
    // Find spectrum's workspace index
    auto it = spec2indexmap.find(specids[i]);
    if (it == spec2indexmap.end()) {
      stringstream errss;
      errss << "Spectrum Number " << specids[i] << " is not found. "
            << "Instrument won't be edited for this spectrum. \n";
      g_log.error(errss.str());
      throw std::runtime_error(errss.str());
    }

    // Store and set value
    size_t workspaceindex = it->second;

    storL2s[workspaceindex] = l2s[i];
    stor2Thetas[workspaceindex] = tths[i];
    storPhis[workspaceindex] = phis[i];
    if (renameDetID)
      storDetIDs[workspaceindex] = vec_detids[i];

    g_log.debug() << "workspace index = " << workspaceindex
                  << " is for Spectrum " << specids[i] << '\n';
  }

  // Generate a new instrument
  // Name of the new instrument
  std::string name = std::string(getProperty("InstrumentName"));
  if (name.empty()) {
    // Use the original L1
    if (!originstrument) {
      std::string errmsg(
          "It is not supported that InstrumentName is not given, ",
          "while there is no instrument associated to input workspace.");
      g_log.error(errmsg);
      throw std::runtime_error(errmsg);
    }
    name = originstrument->getName();
  }

  // Create a new instrument from scratch any way.
  auto instrument = boost::make_shared<Geometry::Instrument>(name);
  if (!bool(instrument)) {
    stringstream errss;
    errss << "Trying to use a Parametrized Instrument as an Instrument.";
    g_log.error(errss.str());
    throw std::runtime_error(errss.str());
  }

  // Set up source and sample information
  Geometry::ObjComponent *samplepos =
      new Geometry::ObjComponent("Sample", instrument.get());
  instrument->add(samplepos);
  instrument->markAsSamplePos(samplepos);
  samplepos->setPos(0.0, 0.0, 0.0);

  Geometry::ObjComponent *source =
      new Geometry::ObjComponent("Source", instrument.get());
  instrument->add(source);
  instrument->markAsSource(source);
  source->setPos(0.0, 0.0, -1.0 * l1);

  // Add/copy detector information
  auto indexInfo = workspace->indexInfo();
  std::vector<detid_t> detIDs;
  for (size_t i = 0; i < workspace->getNumberHistograms(); i++) {
    // Create a new detector.
    //    (Instrument will take ownership of pointer so no need to delete.)
    detid_t newdetid;
    if (renameDetID)
      newdetid = storDetIDs[i];
    else
      newdetid = detid_t(i) + 100;
    Geometry::Detector *detector =
        new Geometry::Detector("det", newdetid, samplepos);

    // Set up new detector parameters related to new instrument
    double l2 = storL2s[i];
    double tth = stor2Thetas[i];
    double phi = storPhis[i];

    Kernel::V3D pos;
    pos.spherical(l2, tth, phi);
    detector->setPos(pos);

    // Add new detector to spectrum and instrument
    // Good and do some debug output
    g_log.debug() << "Orignal spectrum " << indexInfo.spectrumNumber(i)
                  << "has " << indexInfo.detectorIDs(i).size()
                  << " detectors. \n";

    detIDs.push_back(newdetid);
    instrument->add(detector);
    instrument->markAsDetector(detector);

  } // ENDFOR workspace index
  indexInfo.setDetectorIDs(std::move(detIDs));
  workspace->setIndexInfo(indexInfo);

  // Add the new instrument
  workspace->setInstrument(instrument);
}
Example #30
0
  void Iqt::plotInput(const QString& wsname)
  {
    MatrixWorkspace_sptr workspace;
    try
    {
      workspace = Mantid::API::AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(wsname.toStdString());
    }
    catch(Mantid::Kernel::Exception::NotFoundError&)
    {
      showMessageBox(QString("Unable to retrieve workspace: " + wsname));
      return;
    }

    m_uiForm.ppPlot->clear();
    m_uiForm.ppPlot->addSpectrum("Sample", workspace, 0);

    auto xRangeSelector = m_uiForm.ppPlot->getRangeSelector("FuryRange");

    try
    {
      QPair<double, double> range = m_uiForm.ppPlot->getCurveRange("Sample");
      double rounded_min(range.first);
      double rounded_max(range.second);
      const std::string instrName(workspace->getInstrument()->getName());
      if(instrName == "BASIS")
      {
        xRangeSelector->setRange(range.first, range.second);
        m_dblManager->setValue(m_properties["ELow"], rounded_min);
        m_dblManager->setValue(m_properties["EHigh"], rounded_max);
        m_dblManager->setValue(m_properties["EWidth"], 0.0004);
        m_dblManager->setValue(m_properties["SampleBinning"], 1);
      }
      else
      {
        rounded_min = floor(rounded_min * 10 + 0.5) / 10.0;
        rounded_max = floor(rounded_max * 10 + 0.5) / 10.0;

        //corrections for if nearest value is outside of range
        if (rounded_max > range.second)
        {
          rounded_max -= 0.1;
        }

        if(rounded_min < range.first)
        {
          rounded_min += 0.1;
        }

        //check incase we have a really small range
        if (fabs(rounded_min) > 0 && fabs(rounded_max) > 0)
        {
          xRangeSelector->setRange(rounded_min, rounded_max);
          m_dblManager->setValue(m_properties["ELow"], rounded_min);
          m_dblManager->setValue(m_properties["EHigh"], rounded_max);
        }
        else
        {
          xRangeSelector->setRange(range.first, range.second);
          m_dblManager->setValue(m_properties["ELow"], range.first);
          m_dblManager->setValue(m_properties["EHigh"], range.second);
        }
        //set default value for width
        m_dblManager->setValue(m_properties["EWidth"], 0.005);
      }
    }
    catch(std::invalid_argument & exc)
    {
      showMessageBox(exc.what());
    }

    calculateBinning();
  }