Exemplo n.º 1
0
/**
 * @brief IntegratePeaksCWSD::simplePeakIntegration
 * Purpose:
 *   Integrate a single crystal peak with the simplest algorithm, i.e.,
 *   by adding all the signal with normalization to monitor counts
 * Requirements:
 *   Valid MDEventWorkspace
 *   Valid PeaksWorkspace
 * Guarantees:
 *   A valid value is given
 */
void IntegratePeaksCWSD::simplePeakIntegration(
    const std::vector<detid_t> &vecMaskedDetID,
    const std::map<int, signal_t> &run_monitor_map) {
  // Check requirements
  if (!m_inputWS)
    throw std::runtime_error("MDEventWorkspace is not defined.");

  // Go through to get value
  auto mditer = m_inputWS->createIterator();
  size_t nextindex = 1;
  bool scancell = true;
  // size_t currindex = 0;

  // Assuming that MDEvents are grouped by run number, there is no need to
  // loop up the map for peak center and monitor counts each time
  int current_run_number = -1;
  signal_t current_monitor_counts = 0;
  Kernel::V3D current_peak_center = m_peakCenter;

  // signal_t total_signal = 0;
  double min_distance = 10000000;
  double max_distance = -1;

  while (scancell) {
    // Go through all the MDEvents in one cell.
    size_t numeventincell = mditer->getNumEvents();

    for (size_t iev = 0; iev < numeventincell; ++iev) {
      // Get signal to add and skip if signal is zero
      signal_t signal = mditer->getInnerSignal(iev);
      if (signal <= THRESHOLD_SIGNAL)
        continue;

      uint16_t run_number = mditer->getInnerRunIndex(iev);
      int run_number_i = static_cast<int>(run_number);

      /* debug: record raw signals
      if (run_number_i % 1000 == testrunnumber)
      {
        total_signal += signal;
        ++ num_det;
      }
      // ... debug */

      // Check whether this detector is masked
      if (!vecMaskedDetID.empty()) {
        detid_t detid = mditer->getInnerDetectorID(iev);
        std::vector<detid_t>::const_iterator it;

        it = find(vecMaskedDetID.begin(), vecMaskedDetID.end(), detid);
        if (it != vecMaskedDetID.end()) {
          // The detector ID is found among masked detector IDs
          // Skip this event and move to next

          /* debug: record masked detectors
          if (run_number_i % 1000 == testrunnumber)
          {
            num_masked_det += 1;
            g_log.warning() << "Masked detector ID = " << detid << ", Signal = "
          << signal << "\n";
          }
          // ... debug */

          continue;
        }
      }

      /* debug: record unmasked detectors
      if (run_number_i % 1000 == testrunnumber)
        num_unmasked_det += 1;
      // ... debug */

      // Check whether to update monitor counts and peak center
      if (current_run_number != run_number_i) {
        // update run number
        current_run_number = run_number_i;
        // update monitor counts
        if (m_normalizeByMonitor) {
          std::map<int, signal_t>::const_iterator m_finder =
              run_monitor_map.find(current_run_number);
          if (m_finder != run_monitor_map.end())
            current_monitor_counts = m_finder->second;
          else {
            std::stringstream errss;
            errss << "Unable to find run number " << current_run_number
                  << " in monitor counts map";
            throw std::runtime_error(errss.str());
          }
        } else {
          current_monitor_counts = 1.;
        }

        // update peak center
        if (!m_useSinglePeakCenterFmUser)
          current_peak_center = m_runPeakCenterMap[current_run_number];
      }

      // calculate distance
      float tempx = mditer->getInnerPosition(iev, 0);
      float tempy = mditer->getInnerPosition(iev, 1);
      float tempz = mditer->getInnerPosition(iev, 2);
      Kernel::V3D pixel_pos(tempx, tempy, tempz);
      double distance = current_peak_center.distance(pixel_pos);

      /* debug: record unmasked signal
      if (run_number_i % 1000 == testrunnumber)
      {
        total_unmasked_signal += signal;
      }
      // ... debug */

      if (distance < m_peakRadius) {
        // FIXME - Is it very costly to use map each time???
        // total_signal += signal/current_monitor_counts;
        m_runPeakCountsMap[run_number] += signal / current_monitor_counts;
      } else {
        g_log.debug() << "Out of radius " << distance << " > " << m_peakRadius
                      << ": Center = " << current_peak_center.toString()
                      << ", Pixel  = " << pixel_pos.toString() << "\n";
      }

      if (distance < min_distance)
        min_distance = distance;
      if (distance > max_distance)
        max_distance = distance;
    }

    // Advance to next cell
    if (mditer->next()) {
      // advance to next cell
      mditer->jumpTo(nextindex);
      ++nextindex;
    } else {
      // break the loop
      scancell = false;
    }
  } // END-WHILE (scan-cell)

  // Summarize
  g_log.notice() << "Distance range is " << min_distance << ", " << max_distance
                 << "\n";

  /*
  g_log.warning() << "Debug output: run 13: Number masked detectors = " <<
  num_masked_det
                  << ", Total signal = " << total_signal << "\n";
  g_log.warning() << "  Number of unmasked detectors = " << num_unmasked_det
                  << ", Total unmasked signal = " << total_unmasked_signal <<
  "\n";
  g_log.warning() << "  Number of total detectors = " << num_det << "\n";
  */
}
Exemplo n.º 2
0
/**
 * Create an output event workspace filled with data simulated with the fitting
 * function.
 * @param baseName :: The base name for the workspace
 * @param inputWorkspace :: The input workspace.
 * @param values :: The calculated values
 * @param outputWorkspacePropertyName :: The property name
 */
boost::shared_ptr<API::Workspace> FitMD::createEventOutputWorkspace(
    const std::string &baseName, const API::IMDEventWorkspace &inputWorkspace,
    const API::FunctionValues &values,
    const std::string &outputWorkspacePropertyName) {
  auto outputWS =
      MDEventFactory::CreateMDWorkspace(inputWorkspace.getNumDims(), "MDEvent");
  // Add events
  // TODO: Generalize to ND (the current framework is a bit limiting)
  auto mdWS = boost::dynamic_pointer_cast<
      DataObjects::MDEventWorkspace<DataObjects::MDEvent<4>, 4>>(outputWS);
  if (!mdWS) {
    return boost::shared_ptr<API::Workspace>();
  }

  // Bins extents and meta data
  for (size_t i = 0; i < 4; ++i) {
    boost::shared_ptr<const Geometry::IMDDimension> inputDim =
        inputWorkspace.getDimension(i);
    Geometry::MDHistoDimensionBuilder builder;
    builder.setName(inputDim->getName());
    builder.setId(inputDim->getDimensionId());
    builder.setUnits(inputDim->getUnits());
    builder.setNumBins(inputDim->getNBins());
    builder.setMin(inputDim->getMinimum());
    builder.setMax(inputDim->getMaximum());
    builder.setFrameName(inputDim->getMDFrame().name());

    outputWS->addDimension(builder.create());
  }

  // Run information
  outputWS->copyExperimentInfos(inputWorkspace);
  // Coordinates
  outputWS->setCoordinateSystem(inputWorkspace.getSpecialCoordinateSystem());
  // Set sensible defaults for splitting behaviour
  BoxController_sptr bc = outputWS->getBoxController();
  bc->setSplitInto(3);
  bc->setSplitThreshold(3000);
  outputWS->initialize();
  outputWS->splitBox();

  auto inputIter = inputWorkspace.createIterator();
  size_t resultValueIndex(0);
  const float errorSq = 0.0;
  do {
    const size_t numEvents = inputIter->getNumEvents();
    const float signal =
        static_cast<float>(values.getCalculated(resultValueIndex));
    for (size_t i = 0; i < numEvents; ++i) {
      coord_t centers[4] = {
          inputIter->getInnerPosition(i, 0), inputIter->getInnerPosition(i, 1),
          inputIter->getInnerPosition(i, 2), inputIter->getInnerPosition(i, 3)};
      mdWS->addEvent(MDEvent<4>(signal, errorSq, inputIter->getInnerRunIndex(i),
                                inputIter->getInnerDetectorID(i), centers));
    }
    ++resultValueIndex;
  } while (inputIter->next());
  delete inputIter;

  // This splits up all the boxes according to split thresholds and sizes.
  auto threadScheduler = new Kernel::ThreadSchedulerFIFO();
  Kernel::ThreadPool threadPool(threadScheduler);
  outputWS->splitAllIfNeeded(threadScheduler);
  threadPool.joinAll();
  outputWS->refreshCache();

  // Store it
  if (!outputWorkspacePropertyName.empty()) {
    declareProperty(
        new API::WorkspaceProperty<API::IMDEventWorkspace>(
            outputWorkspacePropertyName, "", Direction::Output),
        "Name of the output Workspace holding resulting simulated spectrum");
    m_manager->setPropertyValue(outputWorkspacePropertyName,
                                baseName + "Workspace");
    m_manager->setProperty(outputWorkspacePropertyName, outputWS);
  }

  return outputWS;
}