예제 #1
0
void SaveNexusProcessed::appendEventListData(std::vector<T> events,
                                             size_t offset, double *tofs,
                                             float *weights,
                                             float *errorSquareds,
                                             int64_t *pulsetimes) {
  // Do nothing if there are no events.
  if (events.empty())
    return;

  typename std::vector<T>::const_iterator it;
  typename std::vector<T>::const_iterator it_end = events.end();
  size_t i = offset;

  // Fill the C-arrays with the fields from all the events, as requested.
  for (it = events.begin(); it != it_end; it++) {
    if (tofs)
      tofs[i] = it->tof();
    if (weights)
      weights[i] = static_cast<float>(it->weight());
    if (errorSquareds)
      errorSquareds[i] = static_cast<float>(it->errorSquared());
    if (pulsetimes)
      pulsetimes[i] = it->pulseTime().totalNanoseconds();
    i++;
  }
}
예제 #2
0
void UnaryOperation::unaryOperationEventHelper(std::vector<T> &wevector) {

  typename std::vector<T>::iterator it;
  for (it = wevector.begin(); it < wevector.end(); ++it) {
    double yout, eout;
    // Call the abstract function, passing in the current values
    performUnaryOperation(it->tof(), it->weight(),
                          std::sqrt(it->errorSquared()), yout, eout);
    it->m_weight = static_cast<float>(yout);
    it->m_errorSquared = static_cast<float>(eout * eout);
  }
}
예제 #3
0
  void NexusFileIO::writeEventListData( std::vector<T> events, bool writeTOF, bool writePulsetime, bool writeWeight, bool writeError) const
  {
    // Do nothing if there are no events.
    if (events.empty())
      return;

    size_t num = events.size();
    double * tofs = new double[num];
    double * weights = new double[num];
    double * errorSquareds = new double[num];
    int64_t * pulsetimes = new int64_t[num];

    typename std::vector<T>::const_iterator it;
    typename std::vector<T>::const_iterator it_end = events.end();
    size_t i = 0;

    // Fill the C-arrays with the fields from all the events, as requested.
    for (it = events.begin(); it != it_end; it++)
    {
      if (writeTOF) tofs[i] = it->tof();
      if (writePulsetime) pulsetimes[i] = it->pulseTime().totalNanoseconds();
      if (writeWeight) weights[i] = it->weight();
      if (writeError) errorSquareds[i] = it->errorSquared();
      i++;
    }

    // Write out all the required arrays.
    int dims_array[1] = { static_cast<int>(num) };
    // In this mode, compressing makes things extremely slow! Not to be used for managed event workspaces.
    bool compress = true; //(num > 100);
    if (writeTOF)
      NXwritedata("tof", NX_FLOAT64, 1, dims_array, (void *)(tofs), compress);
    if (writePulsetime)
      NXwritedata("pulsetime", NX_INT64, 1, dims_array, (void *)(pulsetimes), compress);
    if (writeWeight)
      NXwritedata("weight", NX_FLOAT32, 1, dims_array, (void *)(weights), compress);
    if (writeError)
      NXwritedata("error_squared", NX_FLOAT32, 1, dims_array, (void *)(errorSquareds), compress);

    // Free mem.
    delete [] tofs;
    delete [] weights;
    delete [] errorSquareds;
    delete [] pulsetimes;
  }
예제 #4
0
size_t ConvToMDEventsWS::convertEventList(size_t workspaceIndex) {

  const Mantid::DataObjects::EventList &el =
      m_EventWS->getEventList(workspaceIndex);
  size_t numEvents = el.getNumberEvents();
  if (numEvents == 0)
    return 0;

  // create local unit conversion class
  UnitsConversionHelper localUnitConv(m_UnitConversion);

  uint32_t detID = m_detID[workspaceIndex];
  uint16_t runIndexLoc = m_RunIndex;

  std::vector<coord_t> locCoord(m_Coord);
  // set up unit conversion and calculate up all coordinates, which depend on
  // spectra index only
  if (!m_QConverter->calcYDepCoordinates(locCoord, workspaceIndex))
    return 0; // skip if any y outsize of the range of interest;
  localUnitConv.updateConversion(workspaceIndex);
  //
  // allocate temporary buffers for MD Events data
  // MD events coordinates buffer
  std::vector<coord_t> allCoord;
  std::vector<float> sig_err;      // array for signal and error.
  std::vector<uint16_t> run_index; // Buffer for run index for each event
  std::vector<uint32_t> det_ids;   // Buffer of det Id-s for each event

  allCoord.reserve(this->m_NDims * numEvents);
  sig_err.reserve(2 * numEvents);
  run_index.reserve(numEvents);
  det_ids.reserve(numEvents);

  // This little dance makes the getting vector of events more general (since
  // you can't overload by return type).
  typename std::vector<T> const *events_ptr;
  getEventsFrom(el, events_ptr);
  const typename std::vector<T> &events = *events_ptr;

  // Iterators to start/end
  typename std::vector<T>::const_iterator it = events.begin();
  typename std::vector<T>::const_iterator it_end = events.end();

  it = events.begin();
  for (; it != it_end; it++) {
    double val = localUnitConv.convertUnits(it->tof());
    double signal = it->weight();
    double errorSq = it->errorSquared();
    if (!m_QConverter->calcMatrixCoord(val, locCoord, signal, errorSq))
      continue; // skip ND outside the range

    sig_err.push_back(float(signal));
    sig_err.push_back(float(errorSq));
    run_index.push_back(runIndexLoc);
    det_ids.push_back(detID);
    allCoord.insert(allCoord.end(), locCoord.begin(), locCoord.end());
  }

  // Add them to the MDEW
  size_t n_added_events = run_index.size();
  m_OutWSWrapper->addMDData(sig_err, run_index, det_ids, allCoord,
                            n_added_events);
  return n_added_events;
}
  void ConvertToDiffractionMDWorkspace::convertEventList(int workspaceIndex, EventList & el)
  {
    size_t numEvents = el.getNumberEvents();
    MDEvents::MDBoxBase<MDEvents::MDLeanEvent<3>,3> * box = ws->getBox();

    // Get the position of the detector there.
    const std::set<detid_t>& detectors = el.getDetectorIDs();
    if (!detectors.empty())
    {
      // Get the detector (might be a detectorGroup for multiple detectors)
      // or might return an exception if the detector is not in the instrument definition
      IDetector_const_sptr det;
      try
      {
        det = m_inWS->getDetector(workspaceIndex);
      }
      catch (Exception::NotFoundError &)
      {
        this->failedDetectorLookupCount++;
        return;
      }

      // Vector between the sample and the detector
      V3D detPos = det->getPos() - samplePos;

      // Neutron's total travelled distance
      double distance = detPos.norm() + l1;

      // Detector direction normalized to 1
      V3D detDir = detPos / detPos.norm();

      // The direction of momentum transfer in the inelastic convention ki-kf
      //  = input beam direction (normalized to 1) - output beam direction (normalized to 1)
      V3D Q_dir_lab_frame = beamDir - detDir;

      // Multiply by the rotation matrix to convert to Q in the sample frame (take out goniometer rotation)
      // (or to HKL, if that's what the matrix is)
      V3D Q_dir = mat * Q_dir_lab_frame;

      // For speed we extract the components.
      coord_t Q_dir_x = coord_t(Q_dir.X());      coord_t Q_dir_y = coord_t(Q_dir.Y());
      coord_t Q_dir_z = coord_t(Q_dir.Z());

      // For lorentz correction, calculate  sin(theta))^2
      double sin_theta_squared = 0;
      if (LorentzCorrection)
      {
        // Scattering angle = 2 theta = angle between neutron beam direction and the detector (scattering) direction
        // The formula for Lorentz Correction is sin(theta), i.e. sin(half the scattering angle)
        double theta = detDir.angle(beamDir) / 2.0;
        sin_theta_squared = sin(theta);
        sin_theta_squared = sin_theta_squared * sin_theta_squared; // square it
      }

      /** Constant that you divide by tof (in usec) to get wavenumber in ang^-1 :
       * Wavenumber (in ang^-1) =  (PhysicalConstants::NeutronMass * distance) / ((tof (in usec) * 1e-6) * PhysicalConstants::h_bar) * 1e-10; */
      const double wavenumber_in_angstrom_times_tof_in_microsec =
          (PhysicalConstants::NeutronMass * distance * 1e-10) / (1e-6 * PhysicalConstants::h_bar);

      //PARALLEL_CRITICAL( convert_tester_output ) { std::cout << "Spectrum " << el.getSpectrumNo() << " beamDir = " << beamDir << " detDir = " << detDir << " Q_dir = " << Q_dir << " conversion factor " << wavenumber_in_angstrom_times_tof_in_microsec << std::endl;  }


      //g_log.information() << wi << " : " << el.getNumberEvents() << " events. Pos is " << detPos << std::endl;
      //g_log.information() << Q_dir.norm() << " Qdir norm" << std::endl;

      // This little dance makes the getting vector of events more general (since you can't overload by return type).
      typename std::vector<T> * events_ptr;
      getEventsFrom(el, events_ptr);
      typename std::vector<T> & events = *events_ptr;

      // Iterators to start/end
      typename std::vector<T>::iterator it = events.begin();
      typename std::vector<T>::iterator it_end = events.end();

      for (; it != it_end; it++)
      {
        // Get the wavenumber in ang^-1 using the previously calculated constant.
        coord_t wavenumber = coord_t(wavenumber_in_angstrom_times_tof_in_microsec / it->tof());

        // Q vector = K_final - K_initial = wavenumber * (output_direction - input_direction)
        coord_t center[3] = {Q_dir_x * wavenumber, Q_dir_y * wavenumber, Q_dir_z * wavenumber};

        // Check that the event is within bounds
        if (center[0] < m_extentsMin[0] || center[0] >= m_extentsMax[0]) continue;
        if (center[1] < m_extentsMin[1] || center[1] >= m_extentsMax[1]) continue;
        if (center[2] < m_extentsMin[2] || center[2] >= m_extentsMax[2]) continue;

        if (LorentzCorrection)
        {
          //double lambda = 1.0/wavenumber;
          // (sin(theta))^2 / wavelength^4
          float correct = float( sin_theta_squared * wavenumber*wavenumber*wavenumber*wavenumber );
          // Push the MDLeanEvent but correct the weight.
          box->addEvent( MDE(float(it->weight()*correct), float(it->errorSquared()*correct*correct), center) );
        }
        else
        {
          // Push the MDLeanEvent with the same weight
          box->addEvent( MDE(float(it->weight()), float(it->errorSquared()), center) );
        }
      }

      // Clear out the EventList to save memory
      if (ClearInputWorkspace)
      {
        // Track how much memory you cleared
        size_t memoryCleared = el.getMemorySize();
        // Clear it now
        el.clear();
        // For Linux with tcmalloc, make sure memory goes back, if you've cleared 200 Megs
        MemoryManager::Instance().releaseFreeMemoryIfAccumulated(memoryCleared, (size_t)2e8);
      }
    }
    prog->reportIncrement(numEvents, "Adding Events");
  }