コード例 #1
0
/** Get instrument geometry setup including L2 for each detector and L1
  */
void CreateLogTimeCorrection::getInstrumentSetup() {
  // 1. Get sample position and source position
  IComponent_const_sptr sample = m_instrument->getSample();
  if (!sample) {
    throw runtime_error("No sample has been set.");
  }
  V3D samplepos = sample->getPos();

  IComponent_const_sptr source = m_instrument->getSource();
  if (!source) {
    throw runtime_error("No source has been set.");
  }
  V3D sourcepos = source->getPos();
  m_L1 = sourcepos.distance(samplepos);

  // 2. Get detector IDs
  std::vector<detid_t> detids = m_instrument->getDetectorIDs(true);
  for (auto &detid : detids) {
    IDetector_const_sptr detector = m_instrument->getDetector(detid);
    V3D detpos = detector->getPos();
    double l2 = detpos.distance(samplepos);
    m_l2map.emplace(detid, l2);
  }

  // 3. Output information
  g_log.information() << "Sample position = " << samplepos << "; "
                      << "Source position = " << sourcepos << ", L1 = " << m_L1
                      << "; "
                      << "Number of detector/pixels = " << detids.size()
                      << ".\n";
}
コード例 #2
0
ファイル: RadiusSum.cpp プロジェクト: mcvine/mantid
double RadiusSum::getMaxDistance(const V3D &centre,
                                 const std::vector<double> &boundary_limits) {

  std::array<double, 2> Xs = {{boundary_limits[0], boundary_limits[1]}};
  std::array<double, 2> Ys = {{boundary_limits[2], boundary_limits[3]}};
  std::array<double, 2> Zs = {{0., 0.}};

  if (boundary_limits.size() == 6) {
    Zs[0] = boundary_limits[4];
    Zs[1] = boundary_limits[5];
  }

  double max_distance = 0;
  for (auto &x : Xs)
    for (auto &y : Ys)
      for (auto &z : Zs) {
        // define all the possible combinations for the limits

        double curr_distance = centre.distance(V3D(x, y, z));

        if (curr_distance > max_distance)
          max_distance = curr_distance; // keep the maximum distance.
      }
  return max_distance;
}
コード例 #3
0
/** Checks whether the track given will pass through this Component.
*  @param track :: The Track object to test (N.B. Will be modified if hits are
* found)
*  @returns The number of track segments added (i.e. 1 if the track enters and
* exits the object once each)
*  @throw NullPointerException if the underlying geometrical Object has not been
* set
*/
int ObjComponent::interceptSurface(Track &track) const {
  // If the form of this component is not defined, throw NullPointerException
  if (!shape())
    throw Kernel::Exception::NullPointerException(
        "ObjComponent::interceptSurface", "shape");

  // TODO: If scaling parameters are ever enabled, would they need need to be
  // used here?
  V3D trkStart = factorOutComponentPosition(track.startPoint());
  V3D trkDirection = takeOutRotation(track.direction());

  Track probeTrack(trkStart, trkDirection);
  int intercepts = shape()->interceptSurface(probeTrack);

  Track::LType::const_iterator it;
  for (it = probeTrack.cbegin(); it != probeTrack.cend(); ++it) {
    V3D in = it->entryPoint;
    this->getRotation().rotate(in);
    // use the scale factor
    in *= getScaleFactor();
    in += this->getPos();
    V3D out = it->exitPoint;
    this->getRotation().rotate(out);
    // use the scale factor
    out *= getScaleFactor();
    out += this->getPos();
    track.addLink(in, out, out.distance(track.startPoint()), *(this->shape()),
                  this->getComponentID());
  }

  return intercepts;
}
コード例 #4
0
  void EstimatePDDetectorResolution::retrieveInstrumentParameters()
  {
#if 0
    // Call SolidAngle to get solid angles for all detectors
    Algorithm_sptr calsolidangle = createChildAlgorithm("SolidAngle", -1, -1, true);
    calsolidangle->initialize();

    calsolidangle->setProperty("InputWorkspace", m_inputWS);

    calsolidangle->execute();
    if (!calsolidangle->isExecuted())
      throw runtime_error("Unable to run solid angle. ");

    m_solidangleWS = calsolidangle->getProperty("OutputWorkspace");
    if (!m_solidangleWS)
      throw runtime_error("Unable to get solid angle workspace from SolidAngle(). ");


    size_t numspec = m_solidangleWS->getNumberHistograms();
    for (size_t i = 0; i < numspec; ++i)
      g_log.debug() << "[DB]: " << m_solidangleWS->readY(i)[0] << "\n";
#endif

    // Calculate centre neutron velocity
    Property* cwlproperty = m_inputWS->run().getProperty("LambdaRequest");
    if (!cwlproperty)
      throw runtime_error("Unable to locate property LambdaRequest as central wavelength. ");
    TimeSeriesProperty<double>* cwltimeseries = dynamic_cast<TimeSeriesProperty<double>* >(cwlproperty);
    if (!cwltimeseries)
      throw runtime_error("LambdaReqeust is not a TimeSeriesProperty in double. ");
    if (cwltimeseries->size() != 1)
      throw runtime_error("LambdaRequest should contain 1 and only 1 entry. ");

    double centrewavelength = cwltimeseries->nthValue(0);
    string unit = cwltimeseries->units();
    if (unit.compare("Angstrom") == 0)
      centrewavelength *= 1.0E-10;
    else
      throw runtime_error("Unit is not recognized");

    m_centreVelocity = PhysicalConstants::h/PhysicalConstants::NeutronMass/centrewavelength;
    g_log.notice() << "Centre wavelength = " << centrewavelength << ", Centre neutron velocity = " << m_centreVelocity << "\n";

    // Calcualte L1 sample to source
    Instrument_const_sptr instrument = m_inputWS->getInstrument();
    V3D samplepos = instrument->getSample()->getPos();
    V3D sourcepos = instrument->getSource()->getPos();
    m_L1 = samplepos.distance(sourcepos);
    g_log.notice() << "L1 = " << m_L1 << "\n";

    return;
  }
コード例 #5
0
bool PeakBackground::isBackground(Mantid::API::IMDIterator *iterator) const {
  if (!HardThresholdBackground::isBackground(iterator)) {
    const VMD &center = iterator->getCenter();
    V3D temp(center[0], center[1], center[2]); // This assumes dims 1, 2, and 3
                                               // in the workspace correspond to
                                               // positions.

    for (int i = 0; i < m_peaksWS->getNumberPeaks(); ++i) {
      const IPeak &peak = m_peaksWS->getPeak(i);
      V3D coords = m_coordFunction(&peak);
      if (coords.distance(temp) < m_radiusEstimate) {
        return false;
      }
    }
  }
  return true;
}
コード例 #6
0
void EstimateResolutionDiffraction::retrieveInstrumentParameters() {
    double centrewavelength = getWavelength();
    g_log.notice() << "Centre wavelength = " << centrewavelength << " Angstrom\n";
    if (centrewavelength > WAVELENGTH_MAX) {
        throw runtime_error("unphysical wavelength used");
    }

    // Calculate centre neutron velocity
    m_centreVelocity = WAVELENGTH_TO_VELOCITY / centrewavelength;
    g_log.notice() << "Centre neutron velocity = " << m_centreVelocity << "\n";

    // Calculate L1 sample to source
    Instrument_const_sptr instrument = m_inputWS->getInstrument();
    V3D samplepos = instrument->getSample()->getPos();
    V3D sourcepos = instrument->getSource()->getPos();
    m_L1 = samplepos.distance(sourcepos);
    g_log.notice() << "L1 = " << m_L1 << "\n";

    return;
}
コード例 #7
0
void EstimateResolutionDiffraction::estimateDetectorResolution() {
    Instrument_const_sptr instrument = m_inputWS->getInstrument();
    V3D samplepos = instrument->getSample()->getPos();

    size_t numspec = m_inputWS->getNumberHistograms();

    double mintwotheta = 10000;
    double maxtwotheta = 0;

    double mint3 = 1;
    double maxt3 = 0;

    size_t count_nodetsize = 0;

    for (size_t i = 0; i < numspec; ++i) {
        // Get detector
        IDetector_const_sptr det = m_inputWS->getDetector(i);

        double detdim;

        boost::shared_ptr<const Detector> realdet =
            boost::dynamic_pointer_cast<const Detector>(det);
        if (realdet) {
            double dy = realdet->getHeight();
            double dx = realdet->getWidth();
            detdim = sqrt(dx * dx + dy * dy) * 0.5;
        } else {
            // Use detector dimension as 0 as no-information
            detdim = 0;
            ++count_nodetsize;
        }

        // Get the distance from detector to source
        V3D detpos = det->getPos();
        double l2 = detpos.distance(samplepos);
        if (l2 < 0)
            throw runtime_error("L2 is negative");

        // Calculate T
        double centraltof = (m_L1 + l2) / m_centreVelocity;

        // Angle
        double twotheta = m_inputWS->detectorTwoTheta(det);
        double theta = 0.5 * twotheta;

        // double solidangle = m_solidangleWS->readY(i)[0];
        double solidangle = det->solidAngle(samplepos);
        double deltatheta = sqrt(solidangle);

        // Resolution
        double t1 = m_deltaT / centraltof;
        double t2 = detdim / (m_L1 + l2);
        double t3 = deltatheta * (cos(theta) / sin(theta));

        double resolution = sqrt(t1 * t1 + t2 * t2 + t3 * t3);

        m_outputWS->dataX(i)[0] = static_cast<double>(i);
        m_outputWS->dataY(i)[0] = resolution;

        if (twotheta > maxtwotheta)
            maxtwotheta = twotheta;
        else if (twotheta < mintwotheta)
            mintwotheta = twotheta;

        if (fabs(t3) < mint3)
            mint3 = fabs(t3);
        else if (fabs(t3) > maxt3)
            maxt3 = fabs(t3);

        g_log.debug() << det->type() << " " << i << "\t\t" << twotheta
                      << "\t\tdT/T = " << t1 * t1 << "\t\tdL/L = " << t2
                      << "\t\tdTheta*cotTheta = " << t3 << "\n";
    }

    g_log.notice() << "2theta range: " << mintwotheta << ", " << maxtwotheta
                   << "\n";
    g_log.notice() << "t3 range: " << mint3 << ", " << maxt3 << "\n";
    g_log.notice() << "Number of detector having NO size information = "
                   << count_nodetsize << "\n";

    return;
}