/**
 * Initializes chopper offsets and time transformer
 *
 * In this method, the instrument dependent parameter for the calculation are
 * setup, so that a PoldiTimeTransformer is available to transfer parameters to
 * the time domain using correct factors etc.
 *
 * @param poldiInstrument :: Valid PoldiInstrumentAdapter
 */
void PoldiSpectrumDomainFunction::initializeInstrumentParameters(
    const PoldiInstrumentAdapter_sptr &poldiInstrument) {
  m_timeTransformer = boost::make_shared<PoldiTimeTransformer>(poldiInstrument);
  m_chopperSlitOffsets = getChopperSlitOffsets(poldiInstrument->chopper());

  if (!poldiInstrument) {
    throw std::runtime_error("No valid POLDI instrument.");
  }

  m_2dHelpers.clear();

  PoldiAbstractDetector_sptr detector = poldiInstrument->detector();
  PoldiAbstractChopper_sptr chopper = poldiInstrument->chopper();

  std::pair<double, double> qLimits = detector->qLimits(1.1, 5.0);

  double dMin = Conversions::qToD(qLimits.second);
  double dMax = Conversions::dToQ(qLimits.first);

  for (int i = 0; i < static_cast<int>(detector->elementCount()); ++i) {
    double sinTheta = sin(detector->twoTheta(i) / 2.0);
    double distance =
        detector->distanceFromSample(i) + chopper->distanceFromSample();
    double deltaD = Conversions::TOFtoD(m_deltaT, distance, sinTheta);

    Poldi2DHelper_sptr curr = boost::make_shared<Poldi2DHelper>();
    curr->setChopperSlitOffsets(distance, sinTheta, deltaD,
                                m_chopperSlitOffsets);
    curr->setDomain(dMin, dMax, deltaD);
    curr->deltaD = deltaD;
    curr->minTOFN = static_cast<int>(
        Conversions::dtoTOF(dMin, distance, sinTheta) / m_deltaT);
    curr->setFactors(m_timeTransformer, static_cast<size_t>(i));

    m_2dHelpers.push_back(curr);
  }
}
/**
 * Initializes chopper offsets and time transformer
 *
 * In this method, the instrument dependent parameter for the calculation are setup, so that a PoldiTimeTransformer is
 * available to transfer parameters to the time domain using correct factors etc.
 *
 * @param poldiInstrument :: PoldiInstrumentAdapter that holds chopper, detector and spectrum
 */
void PoldiSpectrumDomainFunction::initializeInstrumentParameters(const PoldiInstrumentAdapter_sptr &poldiInstrument)
{
    m_timeTransformer = boost::make_shared<PoldiTimeTransformer>(poldiInstrument);
    m_chopperSlitOffsets = getChopperSlitOffsets(poldiInstrument->chopper());

}
Ejemplo n.º 3
0
void PoldiAnalyseResiduals::exec() {
  DataObjects::Workspace2D_sptr measured = getProperty("MeasuredCountData");
  DataObjects::Workspace2D_sptr calculated = getProperty("FittedCountData");

  PoldiInstrumentAdapter_sptr poldiInstrument =
      boost::make_shared<PoldiInstrumentAdapter>(measured);
  // Dead wires need to be taken into account
  PoldiAbstractDetector_sptr deadWireDetector =
      boost::make_shared<PoldiDeadWireDecorator>(measured->getInstrument(),
                                                 poldiInstrument->detector());

  // Since the valid workspace indices are required for some calculations, we
  // extract and keep them
  const std::vector<int> &validWorkspaceIndices =
      deadWireDetector->availableElements();

  // Subtract calculated from measured to get residuals
  DataObjects::Workspace2D_sptr residuals =
      calculateResidualWorkspace(measured, calculated);

  // Normalize residuals so that they are 0.
  normalizeResiduals(residuals, validWorkspaceIndices);

  // Residual correlation core which will be used iteratively.
  PoldiResidualCorrelationCore core(g_log, 0.1);
  core.setInstrument(deadWireDetector, poldiInstrument->chopper());

  double lambdaMin = getProperty("LambdaMin");
  double lambdaMax = getProperty("LambdaMax");
  core.setWavelengthRange(lambdaMin, lambdaMax);

  // One iteration is always necessary
  DataObjects::Workspace2D_sptr sum = core.calculate(residuals, calculated);

  // For keeping track of the relative changes the sum of measured counts is
  // required
  double sumOfMeasuredCounts = sumCounts(measured, validWorkspaceIndices);
  double relativeChange = relativeCountChange(sum, sumOfMeasuredCounts);

  int iteration = 1;

  logIteration(iteration, relativeChange);

  // Iterate until conditions are met, accumulate correlation spectra in sum.
  while (nextIterationAllowed(iteration, relativeChange)) {
    ++iteration;

    DataObjects::Workspace2D_sptr corr = core.calculate(residuals, calculated);
    relativeChange = relativeCountChange(corr, sumOfMeasuredCounts);

    sum = addWorkspaces(sum, corr);

    logIteration(iteration, relativeChange);
  }

  g_log.notice() << "Finished after " << iteration
                 << " iterations, final change=" << relativeChange << std::endl;

  // Return final correlation spectrum.
  setProperty("OutputWorkspace", boost::dynamic_pointer_cast<Workspace>(sum));
}