/** Extract mask information from a workspace containing instrument
  * @return vector of detector IDs of detectors that are masked
  */
std::vector<detid_t> ExtractMaskToTable::extractMaskFromMatrixWorkspace() {
  // Clear input
  std::vector<detid_t> maskeddetids;

  // Get on hold of instrument
  Instrument_const_sptr instrument = m_dataWS->getInstrument();
  if (!instrument)
    throw runtime_error("There is no instrument in input workspace.");

  // Extract
  size_t numdets = instrument->getNumberDetectors();
  vector<detid_t> detids = instrument->getDetectorIDs();

  for (size_t i = 0; i < numdets; ++i) {
    detid_t tmpdetid = detids[i];
    IDetector_const_sptr tmpdetector = instrument->getDetector(tmpdetid);
    bool masked = tmpdetector->isMasked();
    if (masked) {
      maskeddetids.push_back(tmpdetid);
    }
    g_log.debug() << "[DB] Detector No. " << i << ":  ID = " << tmpdetid
                  << ", Masked = " << masked << ".\n";
  }

  g_log.notice() << "Extract mask:  There are " << maskeddetids.size()
                 << " detectors that"
                    " are masked."
                 << ".\n";

  return maskeddetids;
}
示例#2
0
/**
 * @param offsetsWS
 * @param index
 * @return The offset adjusted value of DIFC
 */
double calculateDIFC(OffsetsWorkspace_const_sptr offsetsWS, const size_t index) {
    Instrument_const_sptr instrument = offsetsWS->getInstrument();

    const detid_t detid = getDetID(offsetsWS, index);
    const double offset = getOffset(offsetsWS, detid);

    double l1;
    Kernel::V3D beamline, samplePos;
    double beamline_norm;
    instrument->getInstrumentParameters(l1, beamline, beamline_norm, samplePos);

    Geometry::IDetector_const_sptr detector = instrument->getDetector(detid);

    // the factor returned is what is needed to convert TOF->d-spacing
    // the table is supposed to be filled with DIFC which goes the other way
    const double factor = Instrument::calcConversion(l1, beamline, beamline_norm,
                                      samplePos, detector, offset);
    return 1./factor;
}
示例#3
0
/** Read the scaling information from a file (e.g. merlin_detector.sca) or from
 * the RAW file (.raw)
 *  @param scalingFile :: Name of scaling file .sca
 *  @param truepos :: V3D vector of actual positions as read from the file
 *  @return False if unable to open file, True otherwise
 */
bool SetScalingPSD::processScalingFile(const std::string &scalingFile,
                                       std::vector<Kernel::V3D> &truepos) {
  // Read the scaling information from a text file (.sca extension) or from a
  // raw file (.raw)
  // This is really corrected positions as (r,theta,phi) for each detector
  // Compare these with the instrument values to determine the change in
  // position and the scaling
  // which may be necessary for each pixel if in a tube.
  // movePos is used to updated positions
  std::map<int, Kernel::V3D> posMap;
  std::map<int, double> scaleMap;
  std::map<int, double>::iterator its;

  Instrument_const_sptr instrument = m_workspace->getInstrument();
  if (scalingFile.find(".sca") != std::string::npos ||
      scalingFile.find(".SCA") != std::string::npos) {
    // read a .sca text format file
    // format consists of a short header followed by one line per detector

    std::ifstream sFile(scalingFile.c_str());
    if (!sFile) {
      g_log.error() << "Unable to open scaling file " << scalingFile
                    << std::endl;
      return false;
    }
    std::string str;
    getline(sFile,
            str); // skip header line should be <filename> generated by <prog>
    int detectorCount;
    getline(sFile, str); // get detector count line
    std::istringstream istr(str);
    istr >> detectorCount;
    if (detectorCount < 1) {
      g_log.error("Bad detector count in scaling file");
      throw std::runtime_error("Bad detector count in scaling file");
    }
    truepos.reserve(detectorCount);
    getline(sFile, str); // skip title line
    int detIdLast = -10;
    Kernel::V3D truPosLast, detPosLast;

    Progress prog(this, 0.0, 0.5, detectorCount);
    // Now loop through lines, one for each detector/monitor. The latter are
    // ignored.

    while (getline(sFile, str)) {
      if (str.empty() || str[0] == '#')
        continue;
      std::istringstream istr(str);

      // read 6 values from the line to get the 3 (l2,theta,phi) of interest
      int detIndex, code;
      double l2, theta, phi, offset;
      istr >> detIndex >> offset >> l2 >> code >> theta >> phi;

      // sanity check on angles - l2 should be +ve but sample file has a few -ve
      // values
      // on monitors
      if (theta > 181.0 || theta < -1 || phi < -181 || phi > 181) {
        g_log.error("Position angle data out of range in .sca file");
        throw std::runtime_error(
            "Position angle data out of range in .sca file");
      }
      Kernel::V3D truPos;
      // use abs as correction file has -ve l2 for first few detectors
      truPos.spherical(fabs(l2), theta, phi);
      truepos.push_back(truPos);
      //
      Geometry::IDetector_const_sptr det;
      try {
        det = instrument->getDetector(detIndex);
      } catch (Kernel::Exception::NotFoundError &) {
        continue;
      }
      Kernel::V3D detPos = det->getPos();
      Kernel::V3D shift = truPos - detPos;

      // scaling applied to dets that are not monitors and have sequential IDs
      if (detIdLast == detIndex - 1 && !det->isMonitor()) {
        Kernel::V3D diffI = detPos - detPosLast;
        Kernel::V3D diffT = truPos - truPosLast;
        double scale = diffT.norm() / diffI.norm();
        Kernel::V3D scaleDir = diffT / diffT.norm();
        // Wish to store the scaling in a map, if we already have a scaling
        // for this detector (i.e. from the other side) we average the two
        // values. End of tube detectors only have one scaling estimate.
        scaleMap[detIndex] = scale;
        its = scaleMap.find(detIndex - 1);
        if (its == scaleMap.end())
          scaleMap[detIndex - 1] = scale;
        else
          its->second = 0.5 * (its->second + scale);
        // std::cout << detIndex << scale << scaleDir << std::endl;
      }
      detIdLast = detIndex;
      detPosLast = detPos;
      truPosLast = truPos;
      posMap[detIndex] = shift;
      //
      prog.report();
    }
  } else if (scalingFile.find(".raw") != std::string::npos ||
示例#4
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;
}