Ejemplo n.º 1
0
    /**
     *
     * @param pmap A reference to the ParameterMap instance to update
     * @param det A pointer to the detector whose parameters should be updated
     * @param l2 The new l2 value
     * @param theta The new theta value
     * @param phi The new phi value
     * @param delay The new delay time
     * @param pressure The new pressure value
     * @param thickness The new thickness value
     */
    void LoadDetectorInfo::updateParameterMap(Geometry::ParameterMap & pmap,
                                              const Geometry::IDetector_const_sptr & det,
                                              const double l2, const double theta, const double phi,
                                              const double delay, const double pressure,
                                              const double thickness) const
    {
      // store detector params that are different to instrument level
      if(fabs(delay - m_instDelta) > 1e-06) pmap.addDouble(det->getComponentID(), DELAY_PARAM, delay);
      if(fabs(pressure - m_instPressure) > 1e-06) pmap.addDouble(det->getComponentID(), PRESSURE_PARAM, pressure);
      if(fabs(thickness - m_instThickness) > 1e-06) pmap.addDouble(det->getComponentID(), THICKNESS_PARAM, thickness);

      // move
      if(m_moveDets)
      {
        V3D newPos;
        newPos.spherical(l2, theta, phi);
        // The sample position may not be at 0,0,0
        newPos += m_samplePos;
        ComponentHelper::moveComponent(*det, pmap, newPos, ComponentHelper::Absolute);
      }
    }
Ejemplo n.º 2
0
/**
 * If the InstrumentParameter property is set then it attempts to retrieve the parameter
 * from the component, else it returns the value of the Factor property
 * @param inputWS A pointer to the input workspace
 * @param index The current index to inspect
 * @return Value for the scale factor
 */
double ScaleX::getScaleFactor(const API::MatrixWorkspace_const_sptr & inputWS, const size_t index)
{
  if(m_parname.empty()) return m_algFactor;

  // Try and get factor from component. If we see a DetectorGroup use this will use the first component
  Geometry::IDetector_const_sptr det;
  auto inst = inputWS->getInstrument();

  auto *spec = inputWS->getSpectrum(index);
  const auto & ids = spec->getDetectorIDs();
  const size_t ndets(ids.size());
  if(ndets > 0)
  {
    try
    {
      det = inst->getDetector(*ids.begin());
    }
    catch(Exception::NotFoundError&)
    {
      return 0.0;
    }
  }
  else return 0.0;

  const auto & pmap = inputWS->constInstrumentParameters();
  auto par = pmap.getRecursive(det->getComponentID(), m_parname);
  if(par)
  {
    if(!m_combine) return par->value<double>();
    else return m_binOp(m_algFactor,par->value<double>());
  }
  else
  {
    std::ostringstream os;
    os << "Spectrum at index '" << index << "' has no parameter named '" << m_parname << "'\n";
    throw std::runtime_error(os.str());
  }
}
    /**
     * Updates from a more generic ascii file
     * @param filename :: The input filename
     */
    void UpdateInstrumentFromFile::updateFromAscii(const std::string & filename)
    {
      AsciiFileHeader header;
      const bool isSpectrum = parseAsciiHeader(header);

      Geometry::Instrument_const_sptr inst = m_workspace->getInstrument();
      // Throws for multiple detectors
      const spec2index_map specToIndex(m_workspace->getSpectrumToWorkspaceIndexMap());

      std::ifstream datfile(filename.c_str(), std::ios_base::in);
      const int skipNLines = getProperty("SkipFirstNLines");
      std::string line;
      int lineCount(0);
      while(lineCount < skipNLines)
      {
        std::getline(datfile,line);
        ++lineCount;
      }

      std::vector<double> colValues(header.colCount - 1, 0.0);
      while(std::getline(datfile,line))
      {
        boost::trim(line);
        std::istringstream is(line);
        // Column 0 should be ID/spectrum number
        int32_t detOrSpec(-1000);
        is >> detOrSpec;
        // If first thing read is not a number then skip the line
        if(is.fail())
        {
          g_log.debug() << "Skipping \"" << line << "\". Cannot interpret as list of numbers.\n";
          continue;
        }

        Geometry::IDetector_const_sptr det;
        try
        {
          if(isSpectrum)
          {
            auto it = specToIndex.find(detOrSpec);
            if(it != specToIndex.end())
            {
              const size_t wsIndex = it->second;
              det = m_workspace->getDetector(wsIndex);
            }
            else
            {
              g_log.debug() << "Skipping \"" << line << "\". Spectrum is not in workspace.\n";
              continue;
            }
          }
          else
          {
            det = inst->getDetector(detOrSpec);
          }
        }
        catch(Kernel::Exception::NotFoundError&)
        {
          g_log.debug() << "Skipping \"" << line << "\". Spectrum in workspace but cannot find associated detector.\n";
          continue;
        }

        // Special cases for detector r,t,p. Everything else is
        // attached as an detector parameter
        double R(0.0),theta(0.0), phi(0.0);
        for(size_t i = 1; i < header.colCount; ++i)
        {
          double value(0.0);
          is >> value;
          if(i < header.colCount - 1 && is.eof())
          {
            //If stringstream is at EOF & we are not at the last column then
            // there aren't enought columns in the file
            throw std::runtime_error("UpdateInstrumentFromFile::updateFromAscii - "
                          "File contains fewer than expected number of columns, check AsciiHeader property.");
          }

          if(i == header.rColIdx) R = value;
          else if(i == header.thetaColIdx) theta = value;
          else if(i == header.phiColIdx) phi = value;
          else if(header.detParCols.count(i) == 1)
          {
            Geometry::ParameterMap & pmap = m_workspace->instrumentParameters();
            pmap.addDouble(det->getComponentID(), header.colToName[i],value);
          }
        }
        // Check stream state. stringstream::EOF should have been reached, if not then there is still more to
        // read and the file has more columns than the header indicated
        if(!is.eof())
        {
          throw std::runtime_error("UpdateInstrumentFromFile::updateFromAscii - "
              "File contains more than expected number of columns, check AsciiHeader property.");
        }

        // If not supplied use current values
        double r,t,p;
        det->getPos().getSpherical(r,t,p);
        if(header.rColIdx == 0) R = r;
        if(header.thetaColIdx == 0) theta = t;
        if(header.phiColIdx == 0) phi = p;

        setDetectorPosition(det, static_cast<float>(R), static_cast<float>(theta), static_cast<float>(phi));
      }
    }