Ejemplo n.º 1
0
/**
 * Create workspace to store the structure factor.
 * First spectrum is the real part, second spectrum is the imaginary part
 * X values are the modulus of the Q-vectors
 * @param h5file file identifier
 * @param gws pointer to WorkspaceGroup being filled
 * @param setName string name of dataset
 * @param qvmod vector of Q-vectors' moduli
 * @param sorting_indexes permutation of qvmod indexes to render it in increasing order of momemtum transfer
 */
void LoadSassena::loadFQ(const hid_t& h5file, API::WorkspaceGroup_sptr gws, const std::string setName, const MantidVec &qvmod, const std::vector<int> &sorting_indexes)
{
  const std::string gwsName = this->getPropertyValue("OutputWorkspace");
  int nq = static_cast<int>( qvmod.size() ); //number of q-vectors

  DataObjects::Workspace2D_sptr ws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(API::WorkspaceFactory::Instance().create("Workspace2D", 2, nq, nq));
  const std::string wsName = gwsName + std::string("_") + setName;
  ws->setTitle(wsName);

  double* buf = new double[nq*2];
  this->dataSetDouble(h5file,setName,buf);
  MantidVec& re = ws->dataY(0); // store the real part
  ws->dataX(0) = qvmod;  //X-axis values are the modulus of the q vector
  MantidVec& im = ws->dataY(1); // store the imaginary part
  ws->dataX(1) = qvmod;
  double *curr = buf;
  for(int iq=0; iq<nq; iq++){
    const int index=sorting_indexes[iq];
    re[index]=curr[0];
    im[index]=curr[1];
    curr+=2;
  }
  delete[] buf;

  // Set the Units
  ws->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create("MomentumTransfer");

  this->registerWorkspace(gws,wsName,ws, "X-axis: Q-vector modulus; Y-axis: intermediate structure factor");
}
Ejemplo n.º 2
0
/**
* Perform a call to nxgetslab, via the NexusClasses wrapped methods for a given
* block-size
* @param data :: The NXDataSet object
* @param blocksize :: The block-size to use
* @param period :: The period number
* @param start :: The index within the file to start reading from (zero based)
* @param hist :: The workspace index to start reading into
* @param spec_num :: The spectrum number that matches the hist variable
* @param local_workspace :: The workspace to fill the data with
*/
void LoadISISNexus2::loadBlock(NXDataSetTyped<int> &data, int64_t blocksize,
                               int64_t period, int64_t start, int64_t &hist,
                               int64_t &spec_num,
                               DataObjects::Workspace2D_sptr &local_workspace) {
  data.load(static_cast<int>(blocksize), static_cast<int>(period),
            static_cast<int>(start)); // TODO this is just wrong
  int *data_start = data();
  int *data_end = data_start + m_loadBlockInfo.numberOfChannels;
  int64_t final(hist + blocksize);
  while (hist < final) {
    m_progress->report("Loading data");
    MantidVec &Y = local_workspace->dataY(hist);
    Y.assign(data_start, data_end);
    data_start += m_detBlockInfo.numberOfChannels;
    data_end += m_detBlockInfo.numberOfChannels;
    MantidVec &E = local_workspace->dataE(hist);
    std::transform(Y.begin(), Y.end(), E.begin(), dblSqrt);
    // Populate the workspace. Loop starts from 1, hence i-1
    local_workspace->setX(hist, m_tof_data);
    if (m_load_selected_spectra) {
      // local_workspace->getAxis(1)->setValue(hist,
      // static_cast<specid_t>(spec_num));
      auto spec = local_workspace->getSpectrum(hist);
      specid_t specID = m_specInd2specNum_map.at(hist);
      // set detectors corresponding to spectra Number
      spec->setDetectorIDs(m_spec2det_map.getDetectorIDsForSpectrumNo(specID));
      // set correct spectra Number
      spec->setSpectrumNo(specID);
    }

    ++hist;
    ++spec_num;
  }
}
Ejemplo n.º 3
0
/** Finalizes the calculation of the correlation spectrum
  *
  * This method offers a variable way of using the correlation spectrum
  *calculated previously.
  * The base version converts to Q and creates an appropriate output workspace.
  *
  * @param correctedCorrelatedIntensities :: Intensities of correlation
  *spectrum.
  * @param dValues :: d-spacings at which the spectrum was calculated.
  * @return A workspace containing the correlation spectrum.
  */
DataObjects::Workspace2D_sptr PoldiAutoCorrelationCore::finalizeCalculation(
    const std::vector<double> &correctedCorrelatedIntensities,
    const std::vector<double> &dValues) const {
  /* Finally, the d-Values are converted to q-Values for plotting etc. and
   * inserted into the output workspace. */
  size_t dCount = dValues.size();
  std::vector<double> qValues(dCount);

  PARALLEL_FOR_NO_WSP_CHECK()
  for (int i = 0; i < static_cast<int>(dCount); ++i) {
    qValues[dCount - i - 1] = Conversions::dToQ(dValues[i]);
  }

  m_logger.information() << "  Setting result..." << std::endl;
  DataObjects::Workspace2D_sptr outputWorkspace =
      boost::dynamic_pointer_cast<Mantid::DataObjects::Workspace2D>(
          WorkspaceFactory::Instance().create("Workspace2D", 1, dValues.size(),
                                              dValues.size()));

  outputWorkspace->getAxis(0)->setUnit("MomentumTransfer");

  outputWorkspace->dataY(0) = correctedCorrelatedIntensities;

  outputWorkspace->setX(0, qValues);

  return outputWorkspace;
}
Ejemplo n.º 4
0
/** Load in a single spectrum taken from a NeXus file
*  @param hist ::     The workspace index
*  @param i ::        The spectrum index
*  @param specNo ::   The spectrum number
*  @param nxload ::   A reference to the MuonNeXusReader object
*  @param lengthIn :: The number of elements in a spectrum
*  @param localWorkspace :: A pointer to the workspace in which the data will be
* stored
*/
void LoadMuonNexus1::loadData(size_t hist, specid_t &i, specid_t specNo, MuonNexusReader &nxload,
                              const int64_t lengthIn,
                              DataObjects::Workspace2D_sptr localWorkspace) {
  // Read in a spectrum
  // Put it into a vector, discarding the 1st entry, which is rubbish
  // But note that the last (overflow) bin is kept
  // For Nexus, not sure if above is the case, hence give all data for now
  MantidVec &Y = localWorkspace->dataY(hist);
  Y.assign(nxload.counts + i * lengthIn,
           nxload.counts + i * lengthIn + lengthIn);

  // Create and fill another vector for the errors, containing sqrt(count)
  MantidVec &E = localWorkspace->dataE(hist);
  typedef double (*uf)(double);
  uf dblSqrt = std::sqrt;
  std::transform(Y.begin(), Y.end(), E.begin(), dblSqrt);
  // Populate the workspace. Loop starts from 1, hence i-1

  // Create and fill another vector for the X axis  
  float *timeChannels = new float[lengthIn+1]();
  nxload.getTimeChannels(timeChannels, static_cast<const int>(lengthIn+1));
  // Put the read in array into a vector (inside a shared pointer)
  boost::shared_ptr<MantidVec> timeChannelsVec(
    new MantidVec(timeChannels, timeChannels + lengthIn+1));

  localWorkspace->setX(hist, timeChannelsVec);
  localWorkspace->getSpectrum(hist)->setSpectrumNo(specNo);

  // Clean up
  delete[] timeChannels;

}
Ejemplo n.º 5
0
/**
 * load vectors onto a Workspace2D with 3 bins (the three components of the
 * vectors)
 * dataX for the origin of the vector (assumed (0,0,0) )
 * dataY for the tip of the vector
 * dataE is assumed (0,0,0), no errors
 * @param h5file file identifier
 * @param gws pointer to WorkspaceGroup being filled
 * @param sorting_indexes permutation of qvmod indexes to render it in
 * increasing order of momemtum transfer
 */
const MantidVec LoadSassena::loadQvectors(const hid_t &h5file,
                                          API::WorkspaceGroup_sptr gws,
                                          std::vector<int> &sorting_indexes) {

  const std::string gwsName = this->getPropertyValue("OutputWorkspace");
  const std::string setName("qvectors");

  hsize_t dims[3];
  if (dataSetInfo(h5file, setName, dims) < 0) {
    throw Kernel::Exception::FileError(
        "Unable to read " + setName + " dataset info:", m_filename);
  }
  int nq = static_cast<int>(dims[0]); // number of q-vectors
  double *buf = new double[nq * 3];
  this->dataSetDouble(h5file, "qvectors", buf);

  MantidVec qvmod; // store the modulus of the vector
  double *curr = buf;
  for (int iq = 0; iq < nq; iq++) {
    qvmod.push_back(
        sqrt(curr[0] * curr[0] + curr[1] * curr[1] + curr[2] * curr[2]));
    curr += 3;
  }

  if (getProperty("SortByQVectors")) {
    std::vector<mypair> qvmodpair;
    for (int iq = 0; iq < nq; iq++)
      qvmodpair.push_back(mypair(qvmod[iq], iq));
    std::sort(qvmodpair.begin(), qvmodpair.end(), compare);
    for (int iq = 0; iq < nq; iq++)
      sorting_indexes.push_back(qvmodpair[iq].second);
    std::sort(qvmod.begin(), qvmod.end());
  } else
    for (int iq = 0; iq < nq; iq++)
      sorting_indexes.push_back(iq);

  DataObjects::Workspace2D_sptr ws =
      boost::dynamic_pointer_cast<DataObjects::Workspace2D>(
          API::WorkspaceFactory::Instance().create("Workspace2D", nq, 3, 3));
  std::string wsName = gwsName + std::string("_") + setName;
  ws->setTitle(wsName);

  for (int iq = 0; iq < nq; iq++) {
    MantidVec &Y = ws->dataY(iq);
    const int index = sorting_indexes[iq];
    curr = buf + 3 * index;
    Y.assign(curr, curr + 3);
  }
  delete[] buf;

  ws->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create(
      "MomentumTransfer"); // Set the Units

  this->registerWorkspace(
      gws, wsName, ws, "X-axis: origin of Q-vectors; Y-axis: tip of Q-vectors");
  return qvmod;
}
Ejemplo n.º 6
0
/// Adds the specified value to all spectra specified by the given workspace
/// indices.
void PoldiAnalyseResiduals::addValue(
    DataObjects::Workspace2D_sptr &workspace, double value,
    const std::vector<int> &workspaceIndices) const {
  for (size_t i = 0; i < workspaceIndices.size(); ++i) {
    MantidVec &counts = workspace->dataY(workspaceIndices[i]);
    for (size_t j = 0; j < counts.size(); ++j) {
      counts[j] += value;
    }
  }
}
Ejemplo n.º 7
0
/**
 * Convenience function to store a detector value into a given spectrum.
 * Note that this type of data doesn't use TOD, so that we use a single dummy
 * bin in X. Each detector is defined as a spectrum of length 1.
 * @param ws: workspace
 * @param specID: ID of the spectrum to store the value in
 * @param value: value to store [count]
 * @param error: error on the value [count]
 * @param wavelength: wavelength value [Angstrom]
 * @param dwavelength: error on the wavelength [Angstrom]
 */
void store_value(DataObjects::Workspace2D_sptr ws, int specID, double value,
                 double error, double wavelength, double dwavelength) {
  MantidVec &X = ws->dataX(specID);
  MantidVec &Y = ws->dataY(specID);
  MantidVec &E = ws->dataE(specID);
  // The following is mostly to make Mantid happy by defining a histogram with
  // a single bin around the neutron wavelength
  X[0] = wavelength - dwavelength / 2.0;
  X[1] = wavelength + dwavelength / 2.0;
  Y[0] = value;
  E[0] = error;
  ws->getSpectrum(specID)->setSpectrumNo(specID);
}
Ejemplo n.º 8
0
    /** Read in a single spectrum from the raw file
     *  @param tcbs ::     The vector containing the time bin boundaries
     *  @param hist ::     The workspace index
     *  @param i ::        The spectrum number
     *  @param iraw ::     A reference to the ISISRAW object
     *  @param lengthIn :: The number of elements in a spectrum
     *  @param spectrum :: Pointer to the array into which the spectrum will be read
     *  @param localWorkspace :: A pointer to the workspace in which the data will be stored
     */
    void LoadRaw::loadData(const MantidVecPtr::ptr_type& tcbs, int32_t hist, specid_t& i, ISISRAW& iraw, const int& lengthIn, int* spectrum, DataObjects::Workspace2D_sptr localWorkspace)
    {
      // Read in a spectrum
      memcpy(spectrum, iraw.dat1 + i * lengthIn, lengthIn * sizeof(int));
      // Put it into a vector, discarding the 1st entry, which is rubbish
      // But note that the last (overflow) bin is kept
      MantidVec& Y = localWorkspace->dataY(hist);
      Y.assign(spectrum + 1, spectrum + lengthIn);
      // Create and fill another vector for the errors, containing sqrt(count)
      MantidVec& E = localWorkspace->dataE(hist);
      std::transform(Y.begin(), Y.end(), E.begin(), dblSqrt);
      // Populate the workspace. Loop starts from 1, hence i-1
      localWorkspace->setX(hist, tcbs);

      localWorkspace->getAxis(1)->setValue(hist, i);
      // NOTE: Raw numbers go straight into the workspace
      //     - no account taken of bin widths/units etc.
    }
Ejemplo n.º 9
0
 /**
 * Perform a call to nxgetslab, via the NexusClasses wrapped methods for a given blocksize
 * @param data :: The NXDataSet object
 * @param blocksize :: The blocksize to use
 * @param period :: The period number
 * @param start :: The index within the file to start reading from (zero based)
 * @param hist :: The workspace index to start reading into
 * @param spec_num :: The spectrum number that matches the hist variable
 * @param local_workspace :: The workspace to fill the data with
 */
 void LoadISISNexus2::loadBlock(NXDataSetTyped<int> & data, int64_t blocksize, int64_t period, int64_t start,
     int64_t &hist, int64_t& spec_num,
   DataObjects::Workspace2D_sptr local_workspace)
 {
   data.load(static_cast<int>(blocksize), static_cast<int>(period), static_cast<int>(start)); // TODO this is just wrong
   int *data_start = data();
   int *data_end = data_start + m_numberOfChannels;
   int64_t final(hist + blocksize);
   while( hist < final )
   {
     m_progress->report("Loading data");
     MantidVec& Y = local_workspace->dataY(hist);
     Y.assign(data_start, data_end);
     data_start += m_numberOfChannels; data_end += m_numberOfChannels;
     MantidVec& E = local_workspace->dataE(hist);
     std::transform(Y.begin(), Y.end(), E.begin(), dblSqrt);
     // Populate the workspace. Loop starts from 1, hence i-1
     local_workspace->setX(hist, m_tof_data);
     local_workspace->getAxis(1)->spectraNo(hist)= static_cast<specid_t>(spec_num);
     ++hist;
     ++spec_num;
   }
 }
Ejemplo n.º 10
0
/** Select background points
  */
void ProcessBackground::selectFromGivenXValues() {
  // Get special input properties
  std::vector<double> bkgdpoints = getProperty("BackgroundPoints");
  string mode = getProperty("BackgroundPointSelectMode");

  // Construct background workspace for fit
  std::vector<double> realx, realy, reale;
  const MantidVec &vecX = m_dataWS->readX(m_wsIndex);
  const MantidVec &vecY = m_dataWS->readY(m_wsIndex);
  const MantidVec &vecE = m_dataWS->readE(m_wsIndex);
  for (size_t i = 0; i < bkgdpoints.size(); ++i) {
    // Data range validation
    double bkgdpoint = bkgdpoints[i];
    if (bkgdpoint < vecX.front()) {
      g_log.warning() << "Input background point " << bkgdpoint
                      << " is out of lower boundary.  "
                      << "Use X[0] = " << vecX.front() << " instead."
                      << "\n";
      bkgdpoint = vecX.front();
    } else if (bkgdpoint > vecX.back()) {
      g_log.warning() << "Input background point " << bkgdpoint
                      << " is out of upper boundary.  Use X[-1] = "
                      << vecX.back() << " instead."
                      << "\n";
      bkgdpoint = vecX.back();
    }

    // Find the index in
    std::vector<double>::const_iterator it;
    it = std::lower_bound(vecX.begin(), vecX.end(), bkgdpoint);
    size_t index = size_t(it - vecX.begin());

    g_log.debug() << "DBx502 Background Points " << i << " Index = " << index
                  << " For TOF = " << bkgdpoints[i] << " in [" << vecX[0]
                  << ", " << vecX.back() << "] "
                  << "\n";

    // Add to list
    realx.push_back(vecX[index]);
    realy.push_back(vecY[index]);
    reale.push_back(vecE[index]);

  } // ENDFOR (i)

  DataObjects::Workspace2D_sptr bkgdWS =
      boost::dynamic_pointer_cast<DataObjects::Workspace2D>(
          API::WorkspaceFactory::Instance().create("Workspace2D", 1,
                                                   realx.size(), realy.size()));
  for (size_t i = 0; i < realx.size(); ++i) {
    bkgdWS->dataX(0)[i] = realx[i];
    bkgdWS->dataY(0)[i] = realy[i];
    bkgdWS->dataE(0)[i] = reale[i];
  }

  // Select background points according to mode
  if (mode.compare("All Background Points") == 0) {
    // Select (possibly) all background points
    m_outputWS = autoBackgroundSelection(bkgdWS);
  } else if (mode.compare("Input Background Points Only") == 0) {
    // Use the input background points only
    m_outputWS = bkgdWS;
  } else {
    stringstream errss;
    errss << "Background select mode " << mode
          << " is not supported by ProcessBackground.";
    g_log.error(errss.str());
    throw runtime_error(errss.str());
  }

  return;
}
Ejemplo n.º 11
0
    /**
    * Load a given period into the workspace
    * @param period :: The period number to load (starting from 1) 
    * @param entry :: The opened root entry node for accessing the monitor and data nodes
    * @param local_workspace :: The workspace to place the data in
    */
    void LoadISISNexus2::loadPeriodData(int64_t period, NXEntry & entry, DataObjects::Workspace2D_sptr local_workspace)
    {
      int64_t hist_index = 0;
      int64_t period_index(period - 1);
      int64_t first_monitor_spectrum = 0;

      if( !m_monitors.empty() )
      {
        first_monitor_spectrum = m_monitors.begin()->first;
        hist_index = first_monitor_spectrum - 1;
        for(std::map<int64_t,std::string>::const_iterator it = m_monitors.begin();
          it != m_monitors.end(); ++it)
        {
          NXData monitor = entry.openNXData(it->second);
          NXInt mondata = monitor.openIntData();
          m_progress->report("Loading monitor");
          mondata.load(1,static_cast<int>(period-1)); // TODO this is just wrong
          MantidVec& Y = local_workspace->dataY(hist_index);
          Y.assign(mondata(),mondata() + m_numberOfChannels);
          MantidVec& E = local_workspace->dataE(hist_index);
          std::transform(Y.begin(), Y.end(), E.begin(), dblSqrt);
          local_workspace->getAxis(1)->spectraNo(hist_index) = static_cast<specid_t>(it->first);

          NXFloat timeBins = monitor.openNXFloat("time_of_flight");
          timeBins.load();
          local_workspace->dataX(hist_index).assign(timeBins(),timeBins() + timeBins.dim0());
          hist_index++;
        }

        if (first_monitor_spectrum > 1)
        {
          hist_index = 0;
        }
      }
      
      if( m_have_detector )
      {
        NXData nxdata = entry.openNXData("detector_1");
        NXDataSetTyped<int> data = nxdata.openIntData();
        data.open();
        //Start with thelist members that are lower than the required spectrum
        const int * const spec_begin = m_spec.get();
        std::vector<int64_t>::iterator min_end = m_spec_list.end();
        if( !m_spec_list.empty() )
        {
          // If we have a list, by now it is ordered so first pull in the range below the starting block range
          // Note the reverse iteration as we want the last one
          if( m_range_supplied )
          {
            min_end = std::find_if(m_spec_list.begin(), m_spec_list.end(), std::bind2nd(std::greater<int>(), m_spec_min));
          }

          for( std::vector<int64_t>::iterator itr = m_spec_list.begin(); itr < min_end; ++itr )
          {
            // Load each
            int64_t spectra_no = (*itr);
            // For this to work correctly, we assume that the spectrum list increases monotonically
            int64_t filestart = std::lower_bound(spec_begin,m_spec_end,spectra_no) - spec_begin;
            m_progress->report("Loading data");
            loadBlock(data, static_cast<int64_t>(1), period_index, filestart, hist_index, spectra_no, local_workspace);
          }
        }    

        if( m_range_supplied )
        {
          // When reading in blocks we need to be careful that the range is exactly divisible by the blocksize
          // and if not have an extra read of the left overs
          const int64_t blocksize = 8;
          const int64_t rangesize = (m_spec_max - m_spec_min + 1) - m_monitors.size();
          const int64_t fullblocks = rangesize / blocksize;
          int64_t read_stop = 0;
          int64_t spectra_no = m_spec_min;
          if (first_monitor_spectrum == 1)
          {// this if crudely checks whether the monitors are at the begining or end of the spectra
            spectra_no += static_cast<int>(m_monitors.size());
          }
          // For this to work correctly, we assume that the spectrum list increases monotonically
          int64_t filestart = std::lower_bound(spec_begin,m_spec_end,spectra_no) - spec_begin;
          if( fullblocks > 0 )
          {
            read_stop = (fullblocks * blocksize);// + m_monitors.size(); //RNT: I think monitors are excluded from the data
            //for( ; hist_index < read_stop; )
            for(int64_t i = 0; i < fullblocks; ++i)
            {
              loadBlock(data, blocksize, period_index, filestart, hist_index, spectra_no, local_workspace);
              filestart += blocksize;
            }
          }
          int64_t finalblock = rangesize - (fullblocks * blocksize);
          if( finalblock > 0 )
          {
            loadBlock(data, finalblock, period_index, filestart, hist_index, spectra_no,  local_workspace);
          }
        }

        //Load in the last of the list indices
        for( std::vector<int64_t>::iterator itr = min_end; itr < m_spec_list.end(); ++itr )
        {
          // Load each
          int64_t spectra_no = (*itr);
          // For this to work correctly, we assume that the spectrum list increases monotonically
          int64_t filestart = std::lower_bound(spec_begin,m_spec_end,spectra_no) - spec_begin;
          loadBlock(data, 1, period_index, filestart, hist_index, spectra_no, local_workspace);
        }
      }

      try
      {
        const std::string title = entry.getString("title");
        local_workspace->setTitle(title);
        // write the title into the log file (run object)
        local_workspace->mutableRun().addProperty("run_title", title, true);
      }
      catch (std::runtime_error &)
      {
        g_log.debug() << "No title was found in the input file, " << getPropertyValue("Filename") << std::endl;
      }
    }
Ejemplo n.º 12
0
/**
 * Create one workspace to hold the real part and another to hold the imaginary
* part.
 * We symmetrize the structure factor to negative times
 * Y-values are structure factor for each Q-value
 * X-values are time bins
 * @param h5file file identifier
 * @param gws pointer to WorkspaceGroup being filled
 * @param setName string name of dataset
 * @param qvmod vector of Q-vectors' moduli
* @param sorting_indexes permutation of qvmod indexes to render it in increasing
* order of momemtum transfer
*/
void LoadSassena::loadFQT(const hid_t &h5file, API::WorkspaceGroup_sptr gws,
                          const std::string setName, const MantidVec &qvmod,
                          const std::vector<int> &sorting_indexes) {
  const std::string gwsName = this->getPropertyValue("OutputWorkspace");
  int nq = static_cast<int>(qvmod.size()); // number of q-vectors
  const double dt =
      getProperty("TimeUnit"); // time unit increment, in picoseconds;
  hsize_t dims[3];
  if (dataSetInfo(h5file, setName, dims) < 0) {
    throw Kernel::Exception::FileError(
        "Unable to read " + setName + " dataset info:", m_filename);
  }
  int nnt = static_cast<int>(dims[1]); // number of non-negative time points
  int nt = 2 * nnt - 1;                // number of time points
  int origin = nnt - 1;
  double *buf = new double[nq * nnt * 2];
  this->dataSetDouble(h5file, setName, buf);

  DataObjects::Workspace2D_sptr wsRe =
      boost::dynamic_pointer_cast<DataObjects::Workspace2D>(
          API::WorkspaceFactory::Instance().create("Workspace2D", nq, nt, nt));
  const std::string wsReName =
      gwsName + std::string("_") + setName + std::string(".Re");
  wsRe->setTitle(wsReName);

  DataObjects::Workspace2D_sptr wsIm =
      boost::dynamic_pointer_cast<DataObjects::Workspace2D>(
          API::WorkspaceFactory::Instance().create("Workspace2D", nq, nt, nt));
  const std::string wsImName =
      gwsName + std::string("_") + setName + std::string(".Im");
  wsIm->setTitle(wsImName);

  for (int iq = 0; iq < nq; iq++) {
    MantidVec &reX = wsRe->dataX(iq);
    MantidVec &imX = wsIm->dataX(iq);
    MantidVec &reY = wsRe->dataY(iq);
    MantidVec &imY = wsIm->dataY(iq);
    const int index = sorting_indexes[iq];
    double *curr = buf + index * nnt * 2;
    for (int it = 0; it < nnt; it++) {
      reX[origin + it] = it * dt; // time point for the real part
      reY[origin + it] =
          *curr; // real part of the intermediate structure factor
      reX[origin - it] = -it * dt; // symmetric negative time
      reY[origin - it] = *curr;    // symmetric value for the negative time
      curr++;
      imX[origin + it] = it * dt;
      imY[origin + it] = *curr;
      imX[origin - it] = -it * dt;
      imY[origin - it] = -(*curr); // antisymmetric value for negative times
      curr++;
    }
  }
  delete[] buf;

  // Set the Time unit for the X-axis
  wsRe->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create("Label");
  auto unitPtr = boost::dynamic_pointer_cast<Kernel::Units::Label>(
      wsRe->getAxis(0)->unit());
  unitPtr->setLabel("Time", "picoseconds");

  wsIm->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create("Label");
  unitPtr = boost::dynamic_pointer_cast<Kernel::Units::Label>(
      wsIm->getAxis(0)->unit());
  unitPtr->setLabel("Time", "picoseconds");

  // Create a numeric axis to replace the default vertical one
  API::Axis *const verticalAxisRe = new API::NumericAxis(nq);
  API::Axis *const verticalAxisIm = new API::NumericAxis(nq);

  wsRe->replaceAxis(1, verticalAxisRe);
  wsIm->replaceAxis(1, verticalAxisIm);

  // Now set the axis values
  for (int i = 0; i < nq; ++i) {
    verticalAxisRe->setValue(i, qvmod[i]);
    verticalAxisIm->setValue(i, qvmod[i]);
  }

  // Set the axis units
  verticalAxisRe->unit() =
      Kernel::UnitFactory::Instance().create("MomentumTransfer");
  verticalAxisRe->title() = "|Q|";
  verticalAxisIm->unit() =
      Kernel::UnitFactory::Instance().create("MomentumTransfer");
  verticalAxisIm->title() = "|Q|";

  // Set the X axis title (for conversion to MD)
  wsRe->getAxis(0)->title() = "Energy transfer";
  wsIm->getAxis(0)->title() = "Energy transfer";

  // Register the workspaces
  registerWorkspace(
      gws, wsReName, wsRe,
      "X-axis: time; Y-axis: real part of intermediate structure factor");
  registerWorkspace(
      gws, wsImName, wsIm,
      "X-axis: time; Y-axis: imaginary part of intermediate structure factor");
}
Ejemplo n.º 13
0
/**
* Load a given period into the workspace
* @param period :: The period number to load (starting from 1)
* @param entry :: The opened root entry node for accessing the monitor and data
* nodes
* @param local_workspace :: The workspace to place the data in
* @param update_spectra2det_mapping :: reset spectra-detector map to the one
* calculated earlier. (Warning! -- this map has to be calculated correctly!)
*/
void
LoadISISNexus2::loadPeriodData(int64_t period, NXEntry &entry,
                               DataObjects::Workspace2D_sptr &local_workspace,
                               bool update_spectra2det_mapping) {
  int64_t hist_index = 0;
  int64_t period_index(period - 1);
  // int64_t first_monitor_spectrum = 0;

  for (auto block = m_spectraBlocks.begin(); block != m_spectraBlocks.end();
       ++block) {
    if (block->isMonitor) {
      NXData monitor = entry.openNXData(block->monName);
      NXInt mondata = monitor.openIntData();
      m_progress->report("Loading monitor");
      mondata.load(1, static_cast<int>(period - 1)); // TODO this is just wrong
      MantidVec &Y = local_workspace->dataY(hist_index);
      Y.assign(mondata(), mondata() + m_monBlockInfo.numberOfChannels);
      MantidVec &E = local_workspace->dataE(hist_index);
      std::transform(Y.begin(), Y.end(), E.begin(), dblSqrt);

      if (update_spectra2det_mapping) {
        // local_workspace->getAxis(1)->setValue(hist_index,
        // static_cast<specid_t>(it->first));
        auto spec = local_workspace->getSpectrum(hist_index);
        specid_t specID = m_specInd2specNum_map.at(hist_index);
        spec->setDetectorIDs(
            m_spec2det_map.getDetectorIDsForSpectrumNo(specID));
        spec->setSpectrumNo(specID);
      }

      NXFloat timeBins = monitor.openNXFloat("time_of_flight");
      timeBins.load();
      local_workspace->dataX(hist_index)
          .assign(timeBins(), timeBins() + timeBins.dim0());
      hist_index++;
    } else if (m_have_detector) {
      NXData nxdata = entry.openNXData("detector_1");
      NXDataSetTyped<int> data = nxdata.openIntData();
      data.open();
      // Start with the list members that are lower than the required spectrum
      const int *const spec_begin = m_spec.get();
      // When reading in blocks we need to be careful that the range is exactly
      // divisible by the block-size
      // and if not have an extra read of the left overs
      const int64_t blocksize = 8;
      const int64_t rangesize = block->last - block->first + 1;
      const int64_t fullblocks = rangesize / blocksize;
      int64_t spectra_no = block->first;

      // For this to work correctly, we assume that the spectrum list increases
      // monotonically
      int64_t filestart =
          std::lower_bound(spec_begin, m_spec_end, spectra_no) - spec_begin;
      if (fullblocks > 0) {
        for (int64_t i = 0; i < fullblocks; ++i) {
          loadBlock(data, blocksize, period_index, filestart, hist_index,
                    spectra_no, local_workspace);
          filestart += blocksize;
        }
      }
      int64_t finalblock = rangesize - (fullblocks * blocksize);
      if (finalblock > 0) {
        loadBlock(data, finalblock, period_index, filestart, hist_index,
                  spectra_no, local_workspace);
      }
    }
  }

  try {
    const std::string title = entry.getString("title");
    local_workspace->setTitle(title);
    // write the title into the log file (run object)
    local_workspace->mutableRun().addProperty("run_title", title, true);
  } catch (std::runtime_error &) {
    g_log.debug() << "No title was found in the input file, "
                  << getPropertyValue("Filename") << std::endl;
  }
}
Ejemplo n.º 14
0
    /** Executes the algorithm. Reading in the file and creating and populating
     *  the output workspace
     *
     *  @throw Exception::FileError If the RAW file cannot be found/opened
     *  @throw std::invalid_argument If the optional properties are set to invalid values
     */
    void LoadRaw2::exec()
    {
      // Retrieve the filename from the properties
      m_filename = getPropertyValue("Filename");
      LoadRawHelper *helper = new LoadRawHelper;
      FILE* file = helper->openRawFile(m_filename);
      isisRaw->ioRAW(file, true);
      
      std::string title(isisRaw->r_title, 80);
      g_log.information("**** Run title: "+ title + "***");

      // Read in the number of spectra in the RAW file
      m_numberOfSpectra = isisRaw->t_nsp1;
      // Read the number of periods in this file
      m_numberOfPeriods = isisRaw->t_nper;
      // Read the number of time channels (i.e. bins) from the RAW file
      const int channelsPerSpectrum = isisRaw->t_ntc1;
      // Read in the time bin boundaries
      const int lengthIn = channelsPerSpectrum + 1;

      // Call private method to validate the optional parameters, if set
      checkOptionalProperties();

      // Calculate the size of a workspace, given its number of periods & spectra to read
      specid_t total_specs;
      if( m_interval || m_list)
      {
        if (m_interval)
        {
          total_specs = (m_spec_max-m_spec_min+1);
          m_spec_max += 1;
        }
        else
            total_specs = 0;

        if (m_list)
        {
            if (m_interval)
            {
                for(std::vector<specid_t>::iterator it=m_spec_list.begin();it!=m_spec_list.end();)
                    if (*it >= m_spec_min && *it <m_spec_max)
                    {
                        it = m_spec_list.erase(it);
                    }
                    else
                        ++it;

            }
            if (m_spec_list.size() == 0) m_list = false;
            total_specs += static_cast<specid_t>(m_spec_list.size());
        }
      }
      else
      {
        total_specs = m_numberOfSpectra;
        // In this case want all the spectra, but zeroth spectrum is garbage so go from 1 to NSP1
        m_spec_min = 1;
        m_spec_max = m_numberOfSpectra + 1;
      }

      // If there is not enough memory use ManagedRawFileWorkspace2D.
      if ( ConfigService::Instance().getString("ManagedRawFileWorkspace.DoNotUse") != "1" &&
           m_numberOfPeriods == 1 && MemoryManager::Instance().goForManagedWorkspace(total_specs,lengthIn,channelsPerSpectrum) &&
          total_specs == m_numberOfSpectra)
      {
        const std::string cache_option = getPropertyValue("Cache");
        size_t option = find(m_cache_options.begin(),m_cache_options.end(),cache_option) - m_cache_options.begin();
        DataObjects::Workspace2D_sptr localWorkspace =
          DataObjects::Workspace2D_sptr(
          new ManagedRawFileWorkspace2D(m_filename, static_cast<int>(option)));
        progress(0.,"Reading raw file...");
        helper->loadRunParameters(localWorkspace, isisRaw.get());
        runLoadInstrument(localWorkspace );
        runLoadMappingTable(localWorkspace );
        runLoadLog(localWorkspace );
        const int period_number = 1;
        Property* log=createPeriodLog(period_number);
        if(log)
        {
          localWorkspace->mutableRun().addLogData(log);
          localWorkspace->mutableRun().addLogData(createCurrentPeriodLog(period_number));
        }
              localWorkspace->mutableRun().setProtonCharge(isisRaw->rpb.r_gd_prtn_chrg);
        for (int i = 0; i < m_numberOfSpectra; ++i)
          localWorkspace->getAxis(1)->setValue(i, i+1);
        localWorkspace->populateInstrumentParameters();
        setProperty("OutputWorkspace",localWorkspace);
        return;
      }

      float* timeChannels = new float[lengthIn];
      isisRaw->getTimeChannels(timeChannels, lengthIn);
      // Put the read in array into a vector (inside a shared pointer)
      boost::shared_ptr<MantidVec> timeChannelsVec
                          (new MantidVec(timeChannels, timeChannels + lengthIn));

      // Need to extract the user-defined output workspace name
      Property *ws = getProperty("OutputWorkspace");
      std::string localWSName = ws->value();

      Progress pr(this,0.,1.,total_specs * m_numberOfPeriods);

      // Create the 2D workspace for the output
      DataObjects::Workspace2D_sptr localWorkspace = boost::dynamic_pointer_cast<DataObjects::Workspace2D>
               (WorkspaceFactory::Instance().create("Workspace2D",total_specs,lengthIn,lengthIn-1));
      localWorkspace->setTitle(title);
      localWorkspace->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
      // Run parameters
      helper->loadRunParameters(localWorkspace, isisRaw.get());
      delete helper;
      helper = NULL;

      // Loop over the number of periods in the raw file, putting each period in a separate workspace
      for (int period = 0; period < m_numberOfPeriods; ++period) {

        if ( period > 0 )
        {
            localWorkspace =  boost::dynamic_pointer_cast<DataObjects::Workspace2D>
                (WorkspaceFactory::Instance().create(localWorkspace));
        }

        isisRaw->skipData(file,period*(m_numberOfSpectra+1));
        int counter = 0;
        for (int i = 1; i <= m_numberOfSpectra; ++i)
        {
            int histToRead = i + period*(m_numberOfSpectra+1);
            if ((i >= m_spec_min && i < m_spec_max) ||
                (m_list && find(m_spec_list.begin(),m_spec_list.end(),i) != m_spec_list.end()))
            {
                isisRaw->readData(file,histToRead);
                // Copy the data into the workspace vector, discarding the 1st entry, which is rubbish
                // But note that the last (overflow) bin is kept
                MantidVec& Y = localWorkspace->dataY(counter);
                Y.assign(isisRaw->dat1 + 1, isisRaw->dat1 + lengthIn);
                // Fill the vector for the errors, containing sqrt(count)
                MantidVec& E = localWorkspace->dataE(counter);
                std::transform(Y.begin(), Y.end(), E.begin(), dblSqrt);
                // Set the X vector pointer and spectrum number
                localWorkspace->setX(counter, timeChannelsVec);
                localWorkspace->getAxis(1)->setValue(counter, i);
                // NOTE: Raw numbers go straight into the workspace
                //     - no account taken of bin widths/units etc.
                ++counter;
                pr.report();
            }
            else
            {
                isisRaw->skipData(file,histToRead);
            }
        }

        // Just a sanity check
        assert(counter == total_specs);

        std::string outputWorkspace = "OutputWorkspace";
        if (period == 0)
        {
          // Only run the Child Algorithms once
          runLoadInstrument(localWorkspace );
          runLoadMappingTable(localWorkspace );
          runLoadLog(localWorkspace );
          const int period_number = period + 1;
          Property* log=createPeriodLog(period_number);
          if(log)
          {
            localWorkspace->mutableRun().addLogData(log);
            localWorkspace->mutableRun().addLogData(createCurrentPeriodLog(period_number));
          }
          // Set the total proton charge for this run
          // (not sure how this works for multi_period files)
          localWorkspace->mutableRun().setProtonCharge(isisRaw->rpb.r_gd_prtn_chrg);
        }
        else   // We are working on a higher period of a multiperiod raw file
        {
          // Create a WorkspaceProperty for the new workspace of a higher period
          // The workspace name given in the OutputWorkspace property has _periodNumber appended to it
          //                (for all but the first period, which has no suffix)
          std::stringstream suffix;
          suffix << (period+1);
          outputWorkspace += suffix.str();
          std::string WSName = localWSName + "_" + suffix.str();
          declareProperty(new WorkspaceProperty<DataObjects::Workspace2D>(outputWorkspace,WSName,Direction::Output));
          g_log.information() << "Workspace " << WSName << " created. \n";
                         
          //remove previous period data
          std::stringstream index;
          index << (period);
          std::string prevPeriod="PERIOD "+index.str();
          localWorkspace->mutableRun().removeLogData(prevPeriod);
          localWorkspace->mutableRun().removeLogData("current_period");
          //add current period data
          const int period_number = period + 1;
          Property* log=createPeriodLog(period_number);
          if(log)
          {
            localWorkspace->mutableRun().addLogData(log);
            localWorkspace->mutableRun().addLogData(createCurrentPeriodLog(period_number));
          }
        }

        // check if values stored in logfiles should be used to define parameters of the instrument
        localWorkspace->populateInstrumentParameters();

        // Assign the result to the output workspace property
        setProperty(outputWorkspace,localWorkspace);

      } // loop over periods

      // Clean up
      delete[] timeChannels;
      //delete[] spectrum;
      fclose(file);
    }