예제 #1
0
/**
 * Creates a new parameterized instrument for which the parameter values can be
 *changed
 *
 * @param Peaks - a PeaksWorkspace used to get the original instrument.  The
 *instrument from the 0th peak is
 *                the one that is used.
 *
 * NOTE: All the peaks in the PeaksWorkspace must use the same instrument.
 */
boost::shared_ptr<Geometry::Instrument>
PeakHKLErrors::getNewInstrument(PeaksWorkspace_sptr Peaks) const {
  Geometry::Instrument_const_sptr instSave = Peaks->getPeak(0).getInstrument();
  auto pmap = boost::make_shared<Geometry::ParameterMap>();

  if (!instSave) {
    g_log.error(" Peaks workspace does not have an instrument");
    throw std::invalid_argument(" Not all peaks have an instrument");
  }

  if (!hasParameterMap) {
    pmapSv = instSave->getParameterMap();
    hasParameterMap = true;
    if (!instSave->isParametrized()) {

      boost::shared_ptr<Geometry::Instrument> instClone(instSave->clone());
      auto Pinsta = boost::make_shared<Geometry::Instrument>(instSave, pmap);

      instChange = Pinsta;
      IComponent_const_sptr sample = instChange->getSample();
      sampPos = sample->getRelativePos();
    } else // catch(... )
    {
      auto P1 = boost::make_shared<Geometry::Instrument>(
          instSave->baseInstrument(), instSave->makeLegacyParameterMap());
      instChange = P1;
      IComponent_const_sptr sample = instChange->getSample();
      sampPos = sample->getRelativePos();
    }
  }

  if (!instChange) {
    g_log.error("Cannot 'clone' instrument");
    throw std::logic_error("Cannot clone instrument");
  }
  //------------------"clone" orig instruments pmap -------------------

  cLone(pmap, instSave, pmapSv);
  V3D sampOffsets(getParameter("SampleXOffset"), getParameter("SampleYOffset"),
                  getParameter("SampleZOffset"));

  IComponent_const_sptr sample = instChange->getSample();
  pmap->addPositionCoordinate(sample.get(), std::string("x"),
                              sampPos.X() + sampOffsets.X());
  pmap->addPositionCoordinate(sample.get(), std::string("y"),
                              sampPos.Y() + sampOffsets.Y());
  pmap->addPositionCoordinate(sample.get(), std::string("z"),
                              sampPos.Z() + sampOffsets.Z());

  return instChange;
}
예제 #2
0
/** Gets the distances between the source and detectors whose IDs you pass to it
*  @param WS :: the input workspace
*  @param mon0Spec :: Spectrum number of the output from the first monitor
*  @param mon1Spec :: Spectrum number of the output from the second monitor
*  @param monitor0Dist :: the calculated distance to the detector whose ID was
* passed to this function first
*  @param monitor1Dist :: calculated distance to the detector whose ID was
* passed to this function second
*  @throw NotFoundError if no detector is found for the detector ID given
*/
void GetEi::getGeometry(API::MatrixWorkspace_const_sptr WS, specid_t mon0Spec,
                        specid_t mon1Spec, double &monitor0Dist,
                        double &monitor1Dist) const {
    const IComponent_const_sptr source = WS->getInstrument()->getSource();

    // retrieve a pointer to the first detector and get its distance
    size_t monWI = 0;
    try {
        monWI = WS->getIndexFromSpectrumNumber(mon0Spec);
    } catch (std::runtime_error &) {
        g_log.error()
                << "Could not find the workspace index for the monitor at spectrum "
                << mon0Spec << "\n";
        g_log.error() << "Error retrieving data for the first monitor" << std::endl;
        throw std::bad_cast();
    }
    const std::set<detid_t> &dets = WS->getSpectrum(monWI)->getDetectorIDs();

    if (dets.size() != 1) {
        g_log.error() << "The detector for spectrum number " << mon0Spec
                      << " was either not found or is a group, grouped monitors "
                      "are not supported by this algorithm\n";
        g_log.error() << "Error retrieving data for the first monitor" << std::endl;
        throw std::bad_cast();
    }
    IDetector_const_sptr det = WS->getInstrument()->getDetector(*dets.begin());
    monitor0Dist = det->getDistance(*(source.get()));

    // repeat for the second detector
    try {
        monWI = WS->getIndexFromSpectrumNumber(mon0Spec);
    } catch (std::runtime_error &) {
        g_log.error()
                << "Could not find the workspace index for the monitor at spectrum "
                << mon0Spec << "\n";
        g_log.error() << "Error retrieving data for the second monitor\n";
        throw std::bad_cast();
    }
    const std::set<detid_t> &dets2 = WS->getSpectrum(monWI)->getDetectorIDs();
    if (dets2.size() != 1) {
        g_log.error() << "The detector for spectrum number " << mon1Spec
                      << " was either not found or is a group, grouped monitors "
                      "are not supported by this algorithm\n";
        g_log.error() << "Error retrieving data for the second monitor\n";
        throw std::bad_cast();
    }
    det = WS->getInstrument()->getDetector(*dets2.begin());
    monitor1Dist = det->getDistance(*(source.get()));
}
예제 #3
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;
}